Eine Wahl zu treffen zwischen ManualResetEvent oder Thread.Sleep()
Ich bin nicht sicher, welche Strategie zu verabschieden...konzentriere ich mich auf meine operation immer abgeschlossen, aber ich möchte auch halten Sie performance-Probleme auf min zu...es gibt eine Methode namens " Execute (), die hat zu warten (laufen synchron), bis eine operation abgeschlossen ist. Dieser Vorgang geschieht in einem anderen thread. Es gibt 2 Möglichkeiten zur Umsetzung, die gleiche Sache...
Durch die Verwendung von ManualResetEvent
void Execute()
{
taskHandle = new ManualResetEvent(false);
.
.
//delegate task to another thread
.
.
taskHandle.WaitOne();
}
ODER
Durch die Verwendung einer einfachen while-Konstrukt
void Execute()
{
.
.
//delegate task to another thread
.
.
while (!JobCompleted)
Thread.Sleep(1000);
}
Welche der beiden Ansätze soll ich übernehmen...warum?
EDIT:
Q2. Was ist, wenn ich hatte gerade eine leer, während contruct? Was ist der Unterschied...?
while(!JobCompleted);
EDIT: (etwas, was ich gesammelt vor)
http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml - Dieser Artikel sagt manualresets sind vergleichsweise langsamer, weil Sie gehen aus managed code und zurück in...
- Möchte nur darauf hinweisen Thread.Sleep(0) Verwendung. Geben Sie null (0), um anzuzeigen, dass dieser thread unterbrochen werden soll, damit die anderen wartenden threads ausführen. In diesem Fall Sleep(0) ist besser als Schlaf(1000), aber mit WaitHandle ist noch besser geeignet, obwohl.
- Die leere while-Schleife ist im Grunde eine spinwait - es wird vollständig verbrauchen CPU. Nicht zu empfehlen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aus Neugier, warum
ManualResetEvent
und nichtAutoResetEvent
? So oder so, gehen die mit dem OS primitiv über ein Schlaf-check-sleep-Ansatz.Können Sie auch ein
Monitor
lock (entweder explizit durchMonitor.Enter
undMonitor.Exit
oder durch einelock
block), aber der Ansatz sollte sein, auf Grundlage dessen, was Sie eigentlich tun; wenn es ein Szenario von "es gibt nur einen der diese Dinge und ich muss exklusiven Zugriff", dann verwenden Sie eineMonitor
sperren. Wenn es "ich muss warten, bis der andere thread beendet aus anderen Gründen als Ressource access", dann verwenden Sie einAutoResetEvent
oderManualResetEvent
.Vorschläge zu verwenden
Thread.Join
sind gut, wenn (und nur wenn)Thread
ObjektWenn entweder nicht wahr (die Sie keinen Zugriff haben, oder der andere thread wird nicht beendet, es wird nur das signal zu einem "alles klar") dann
Thread.Join
nicht tragfähig.Die schlechteste option ist
while(!JobCompleted);
Da, die Krawatte wird bis der Prozessor mit unnötig prüft der Variablen ohne jede pause dazwischen. Ja, es blockiert thread, bis der Vorgang abgeschlossen ist, aber du wirst max aus der CPU-Auslastung (oder zumindest eine single-core-Wert).
Falle macht die effizientere Nutzung der Prozessoren - Sie sind nicht mit zu wecken, die übergeordneten thread bis zur Umfrage. Der kernel wird Sie aufwachen, wenn das Ereignis ausgelöst wird.
Wenn Sie Zugriff auf die ursprüngliche Thread-Objekt, oder bekommen kann, dass der Zugang, du bist am besten Weg mit
- Thread.Join()
.Edit: Auch, wenn dieser im GUI wie WinForms oder WPF, möchten Sie vielleicht zu prüfen, mit BackgroundWorker
Der größte Nachteil der Verwendung
Thread.Sleep()
ist, dass Sie die Entscheidung, wie lange der thread wartet. Der Vorgang, den Sie warten auf den Mai nehmen mehr oder weniger Zeit, und im Allgemeinen ist es sehr schwierig, genau zu quantifizieren, die Zeit. Wenn der thread schläft zu lange, dann sind Sie nicht die bestmögliche Nutzung von Systemressourcen.Um optimal zu sein, sollten Sie
ManualResetEvent
(oderAutoResetEvent
), so dass der Faden wieder aufgenommen wird, sobald der abhängige Vorgang abgeschlossen ist.ManualResetEvent ist definitiv der Weg zu gehen.
Aus der code-snippet Sie bereitgestellt, es sieht aus wie Sie delegieren die Ausführung in Ihrer Execute-Methode. Wenn dies der Fall ist, und du nur das delegieren einer Aufgabe, warum sind Sie delegieren an einen anderen thread an, wenn Sie haben, die Antwort zu warten? Sie könnten genauso gut führen Sie den Prozess synchron.
Sind Sie wahrscheinlich langsamer als, sagen wir ein Warte - /Puls-combo, die Sie verwenden sollten hier meiner Meinung nach. Aber
Manual/AutoResetEvents
wird so schneller als jedeThread.Sleep(x)
dass Sie, auch wenn Siex = 1
. Und selbst wenn Sie unten das Windows-timer-Auflösung 1ms.Dann einen Kern dreht auf 100%, bis die Bedingung dreht wahr, stehlen Zeit Weg von anderen threads, könnte Sie stattdessen nutzen, um etwas sinnvolles zu tun, wie die Berechnung der frames für die "Angry Birds" - oder die cpu könnte einfach cool off ein bisschen, indem Sie die katastrophalen Auswirkungen der globalen Erwärmung für einige weitere Nanosekunden.
Beide Ansätze das gleiche tun, im Grunde. Die while-Schleife ist bisschen deutlicher jedoch, da Sie angeben können, die Zeit schlafen. Zwar würde ich die XXXResetEvent Klassen, die dazu genutzt werden, um in dem Szenario Ihre arbeiten. Ich würde davon ausgehen das threading-Klassen implementieren könnte, jetzt oder später mit robuster threading-code zu verarbeiten vielleicht thread-Affinität auf multi-core-Prozessoren.