Wie finde ich den Status von ManualResetEvent?

72

Ich verwende eine Instanz von ManualResetEvent, um den Thread-Zugriff auf eine Ressource zu steuern, aber ich habe Probleme damit. Weiß jemand, wie ich beim Debuggen herausfinden kann, wie der Status des Objekts ist?

Das heißt, ich würde gerne wissen, ob das ManualResetEventgerade irgendwelche Threads blockiert und vielleicht sogar wie viele und welche Threads es blockiert.

George Mauer
quelle
22
Nur zur Veranschaulichung, unter .NET 4 kann man jetzt verwenden ManualResetEventSlim, was unter anderem eine IsSetMethode bietet , die angeblich schneller ist als WaitOne(0).
Roman Starkov

Antworten:

91

Führen Sie ein WaitOneEreignis mit einem Timeout-Wert von Null aus.

Es wird true zurückgegeben, wenn das Ereignis festgelegt ist, oder false, wenn das Timeout auftritt. Mit anderen Worten, true -> event ist gesetzt, false -> event ist nicht gesetzt.

Andrew Rollings
quelle
2
Das ist eine gute Idee, der Debugger ermöglicht es mir jedoch, seine Interna zu überprüfen. Kann ich den Status nicht irgendwo dort finden?
George Mauer
1
Hmm ... Keine Ahnung. Ich scheine mich zu erinnern, dass es ein undurchsichtiges Objekt ist und nicht viel Hilfe beim Betrachten. Allerdings können Sie wahrscheinlich den WaitOne-Aufruf im Sofortfenster während des Debuggens ausführen :)
Andrew Rollings
Sie können die Interna nicht überprüfen, da diese Klasse ein Wrapper um ein Betriebssystemkonstrukt ist, das nur durch ein Handle dargestellt wird.
Kent
Was tun, wenn die WaitOne-Auswertung mit "Ausdruck kann nicht ausgewertet werden, da der Code der aktuellen Methode optimiert ist" fehlschlägt. (auf chk Build!)
David Burg
Speichern Sie den Rückgabewert in einer Variablen und / oder verwenden Sie System.Diagnostics.Debug.Write und setzen Sie den Haltepunkt unmittelbar danach?
Andrew Rollings
6

Hier ist Arbeitscode:

private ManualResetEvent pause = new ManualResetEvent(false);
pause.WaitOne(); // caller thread pauses
pause.Set();    // another thread releases paused thread

// Check pause state
public bool IsPaused { get { return !pause.WaitOne(0); } }
fabelhaft
quelle
Nenn es wenigstens IsBlocking. Ich sehe nicht, wie dies die gegebene Antwort verbessert. Ich denke, wir können uns selbst aufschreiben, WaitOne(0)wenn wir die Antwort "Führen Sie ein WaitOneEreignis mit einem Timeout-Wert von Null aus."
Maarten Bodewes
1

Sie können Funktionsaufrufe im Debugger Watch-Fenster ausführen. Fügen Sie mreVariable.WaitOne(0)im Überwachungsfenster einen Anruf hinzu und sehen Sie, wie er ausgewertet wird. Hinweis: Sie sollten dies nicht für AutoResetEvents verwenden, da dies den tatsächlichen Status ändern könnte.

Robert Biro
quelle