[C#] - Methoden abschliessen

Was mir immer noch fehlt, machen beide Threads das gleiche? Wenn ja, warum zwei getrennte Threads?
Im Prinzip ists ja nur ein Thread, der eine Methode in einem anderen Thread per Invoke aufruft.

Zweite Variante: Was ist, wenn du den zweiten Thread erst startest, wenn eben genau diese Methode komplett ausgeführt wurde? Der zweite Thread müsste dann diesen Methodenaufruf nicht mehr beinhalten und könnte dann seine Arbeit durchführen.

Der Thread läuft tagelang durch und reagiert bei verschiedenen Ereignissen durch Korrekturmassnahmen.
Da der Thread ein relativ geringes Pollingintervall hat, kann es durchaus vorkommen, dass er ein und das selbe "Ereigniss" doppelt wahrnimmt, da die Behebung noch nicht vollkommen abgeschlossen ist.

Aber eigentlich ging es um die Frage, wie man ohne einen Variablenoverhead dafür sorgen kann, dass eine Methode sofort wieder verlassen wird, wenn diese bereits ausgeführt wird.

Ich hatte da auf was in der Art
if (locked)
return;

Derzeit liebäugel ich mit einer Liste, in der die Methodennamen als Index und ein boolscher Wert als Wert stehen.

Damit hätte ich nur eine Variable. Scheint mir auch der einzige Weg, da es anscheinend direkt von der c# Syntax her nichts zu geben scheint.
 
Es gäbe da noch das Mutex Objekt. Es wird in der Regel verwendet um ApplicationDomain übergreifend Dinge zu synchronisieren. Kann Dir aber nicht sagen ob es einen relativ hohen Overhead verursachen würde. Habe es bisher lediglich zum verhindern vom Starten mehreren Instanzen einer Anwendung verwendet.
[thread=249969]c# Nur XX Instanzen erlauben - Thread[/thread]

Ich glaube aber langsam aber aus deiner Problemstellung herraus zu erkennen, wie Du das ganze jetzt abfackeln könntest.
Wenn Du in deinen DS Wrapper für jede Aktion ein boolsches Flag einbauen würdest und jede Methode mit dem MethodImpl Attribut versiehst, ließe sich das Doppelte ausführen der Methode verhindern.
Also ungefähr so:
C#:
[MethodImpl(MethodImplOptions.Synchronized)]
public void Stop()
{
        if ( this.stopped ) return;
        // Stopping Playback
        this.stopped = true;
}

//Edit: Dann hättest aber für jede Aktion ein extra Flag. Wenn Du schon eine Enumeration verwendest, die Dir den aktuellen Abspiel-/Aufnahme-Status repräsentiert und Du nicht überall noch exta Flag seinbauen willst, währe eine weitere Möglichkeit einen Queue und eine Hashtable zu verwenden. Als Kommando speicherst zusätzlich den Thread in der Hashtable (Dictionary<KommandoEnum><Thread>), der das Kommando ausführen will. In beide Sammlungen schiebst die auszuführenden Kommandos und ein Thread arbeitet das Ganze ab. Wenn das Kommando in den Queue eingefügt wird, hälst den Thread des Kommandos an (Thread.Suspend) und lässt ihn wieder laufen wenn das Kommando abgearbeitet wurde (Thread.Resume). Wenn ein Kommando bereits vorhanden ist (Dictionary.Keys), wird es dann einfach nicht hinzugefügt und auch nicht abgearbeitet. Wenn das Kommando abgearbeitet wurde entfernst es aus der HT.

Ist vielleicht etwas auwendiger zu implementieren. Hast dann aber im nachhinein nicht überall diesen hässlichen Synchronisierungs-Code. :) Zudem können so auch unterschiedliche Methoden nicht gleichzeitig ausgeführt werden.

Wenn Du das so machen willst, würd ich eine extra Objekt dafür implementieren. Sowas wie DSWrapperSynchronized der von dem richtigen Wrapper ableitet und alle Methoden mit new überschreibt und viá private versteckt. Damit kommst nicht in Versuchung doch mal eine Methode direkt aufzurufen. Danach noch alle Propertys überscheiben und deren Zugriff ebenfalls mit dem DSWrapper ansich synchronisieren (lock( base )).
 
Zuletzt bearbeitet:
Ich weiss, ist denke ich mal ein bissel viel auf einmal. :D
Mit dem Mutex hättest den geringsten Aufwand. Wenn es erstellt werden konnte, weisst das die Methode nicht gerade schon ausgeführt wird. Am Ende der Methode released Du das Mutex wieder. Probier aber mal aus und teste es wegen dem möglichen Overhead.

Oder Du versuchst es mit dem Methodenattribut. Da hast aber hinterher mehr Objektdefinierungen und Synchronisierungs-Code in der eigentlichen Logik.

Die Varinate mit der Warteschlange währe aus meiner Sicht die sauberste aber auch die aufwendigste. Du musst dabei deinen DSWrapper nicht mit Dingen vollstopfen, die mit der eigentlichen Logik gar nichts gemein haben. Dabei kannst zudem auch verhindern das unterschiedliche Methoden gleichzeitig ausgeführt werden. Hie gäbe es aber auch ansich unterschiedliche Möglichkeiten. Der DSWrapperSynchronized bietet eine Methode für das Hinzufügen eines Tasks an oder die Methoden des DSWrapperSynchronized überscheiben die deines DSWrappers und führen darin dann die Tasks aus.

Sag halt Bescheid wenn Du noch Fragen dazu oder Probleme bei der Realisierung hast.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück