Wie entblocke ich threads, die nannten Sie die WaitOne-Methode auf ein AutoResetEvent-Objekt?
Unten ist eine Klasse mit der Methode 'SomeMethod', das veranschaulicht mein problem.
class SomeClass
{
AutoResetEvent theEvent = new AutoResetEvent(false);
//more member declarations
public void SomeMethod()
{
//some code
theEvent.WaitOne();
//more code
}
}
Ist die Methode entwickelt werden, um thread-sicher und wird aufgerufen, in verschiedenen threads. Nun ist meine Frage, wie ist es möglich zu entsperren alle threads, die sogenannten "WaitOne-Methode" auf die "theEvent" Objekt an jedem Punkt der Zeit? Diese Anforderung besteht Häufig bei mein design, weil ich in der Lage sein müssen, um ordnungsgemäß starten und stoppen meine multi-threaded Programm. Es scheint mir, dass es ist ziemlich einfach zu beginnen, ein multi-threaded Programm, aber schwer zu stoppen.
Hier ist, was ich bisher versucht habe, die anscheinend funktioniert. Aber ist das die standard-Vorgehensweise?
public void UnblockAll()
{
do
{
theEvent.Set();
} while (theEvent.WaitOne(0));
}
'UnblockAll' - Methode ist ein Mitglied der 'SomeClass' Klasse. Die hier verwendete Technik beruht auf der MSDN-Dokumentation der WaitOne-Methode. Ich zitiere den entsprechenden Teil der Dokumentation unter:
Wenn millisecondsTimeout null ist, wird die Methode nicht blockiert. Er prüft den Zustand der wait-handle und liefert sofort eine Rückgabe.
In der do..while-Schleife rufe ich die Set-Methode. Dies löst einen einzelnen thread, der möglicherweise blockiert haben, durch einen Aufruf an die WaitOne-Methode (codiert innerhalb der 'SomeMethod' - Methode). Als Nächstes Teste ich den Zustand der "theEvent" Objekt nur wissen ob es signalisiert. Diese Untersuchung erfolgt durch den Aufruf der überladenen version der WaitOne-Methode mit einem Timeout-parameter. Das argument, das ich benutze, wenn ich rufen Sie die WaitOne-Methode ist null, die gemäß der Dokumentation der Ergebnisse in den rufen der Rückkehr sofort mit einem booleschen Wert. Wenn der Rückgabewert true ist, dann wird der "theEvent" Objekt war in einem signalisierten Zustand. Wenn es wenigstens einen einzigen thread blockiert der Aufruf der 'WaitOne-Methode" in der 'SomeMethod' - Methode, die den Aufruf der 'Set' - Methode (codiert in den UnblockAll' - Methode), würde die Sperre. Daher der Aufruf an die 'WaitOne-Methode am Ende der do..while-Anweisung in der 'UnblockAll' Methode false zurück. Der Rückgabewert ist wahr, nur wenn es keine threads blockiert.
Ist die obige Argumentation Recht, und wenn es stimmt, ist die Technik, die ein standard-Weg, um mit meinem problem? Ich bin versucht, die Lösung in Erster Linie auf der .net compact-framework 2.0-Plattform.
Klingt wie Sie wollen ein ManualResetEvent, statt. Auf diese Weise wird es bleiben gesetzt, auch wenn Sie mehrere Zuhörer.
korrigiert die syntax-Fehler im code..
InformationsquelleAutor ghd | 2011-05-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie drei praktikable Möglichkeiten. Jeder hat seine eigenen Vorteile und Nachteile. Wählen Sie die eine, die funktioniert am besten für Ihre spezifische situation.
Option 1 - Umfrage der
WaitHandle
.Anstatt das zu tun, unbestimmte blockieren von anrufen verwenden Sie eine mit einem timeout und wieder den block, wenn ein shutdown-Anforderung wurde nicht gegeben.
Option 2 - Verwenden Sie eine separate
WaitHandle
für die Beantragung shutdownOption 3 - Verwenden
Thread.Interrupt
Nicht zu verwechseln mit der
Thread.Abort
. Abbruch der thread ist definitiv unsicher, aber Unterbrechung eines thread ist völlig anders.Thread.Interrupt
"Sack", der eingebaute blockierende Aufrufe verwendet, die in der BCL einschließlichThread.Join
,WaitHandle.WaitOne
,Thread.Sleep
usw..Net compact framework 2.0 nicht die WaitAny Methode in der WaitHandle-Klasse: - (
Schade. Übrigens habe ich vergessen zu erwähnen eine andere option. Ich bearbeitet meine Antwort.
Unterbrechen ist nicht sicher, wenn Sie call-in-code, den Sie nicht besitzen. Sie unterbrechen können, anderen Völkern wartet.
Ja, guter Punkt.
InformationsquelleAutor Brian Gideon
Ihre routine wahrscheinlich funktionieren die meisten der Zeit, aber ich glaube nicht, dass es keine Garantie dafür, dass einer der wartenden threads wird zurückgesetzt, das Ereignis zwischen der Zeit, dass Ihr shutdown-Schleife setzt und die Zeit, die Ihr shutdown-Schleife prüft es erneut.
Finde ich, dass das AutoResetEvent und ManualResetEvent-Klassen eignen sich für wirklich einfache Szenarien. Jedes mal gibt es etwas seltsam über die Anforderungen, die ich schnell wechseln, desto flexibler Wait Und Pulse pattern.
Wenn Sie benötigen keine bereinigen, könnten Sie Ihren worker-threads, die hintergrund-threads, und dann werden Sie einfach aufhören, wenn der Haupt-thread beendet.
Könnten Sie auch in der Lage sein, zu definieren, eine zweite ManualResetEvent genannt stopRequest und warten auf ein signal von entweder "Ereignis". Jedoch, die möglicherweise nicht unterstützt werden auf der compact-framework.
Das ganze Programm ist organisiert in einer Gruppe kooperierender Komponenten. Einige der Komponenten sind durch mehrere threads. Ich fühle, dass, wenn ich ein Mittel bereitzustellen, ordnungsgemäß Herunterfahren eine Komponente ohne Beeinträchtigung der anderen Komponenten, mein design ist noch nicht abgeschlossen. Daher macht die Fäden im hintergrund ist meine Letzte option.
Ich werde auf jeden Fall die Möglichkeit geben, eine zweite ManualResetEvent versuchen..
InformationsquelleAutor Don Kirkby
Tut thread abort Arbeit für Ihre Rahmen?
InformationsquelleAutor Jay