Gibt es einen besseren warten-Muster für c#?
Ich habe festgestellt, mich Code auf diese Art der Sache ein paar mal.
for (int i = 0; i < 10; i++)
{
if (Thing.WaitingFor())
{
break;
}
Thread.Sleep(sleep_time);
}
if(!Thing.WaitingFor())
{
throw new ItDidntHappenException();
}
Es sieht aus wie schlechter code, gibt es einen besseren Weg, dies zu tun /ist es ein symptom von schlechtem design?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einen viel besseren Weg zur Umsetzung dieses Musters ist es, Ihre
Thing
Objekt machen eine Veranstaltung, auf der die Verbraucher warten kann. Zum Beispiel einManualResetEvent
oderAutoResetEvent
. Dies vereinfacht Ihre consumer-code werden die folgendenDen code auf der
Thing
Seite ist auch nicht wirklich komplexer.ManualResetEvent
geeignet ist in diesem Umstand.Ereignisse verwenden.
Haben Sie das, was Sie warten auf ein Ereignis auslösen, wenn es fertig ist (oder nicht fertig innerhalb der vorgegebenen Zeit) und dann behandeln Sie das Ereignis in Ihre main Anwendung.
So dass Sie nicht haben jede
Sleep
Schleifen.Einer Schleife ist nicht eine SCHRECKLICHE Art und Weise, auf etwas zu warten, wenn es nichts anderes gibt, für das Programm zu tun, während Sie wartet (zum Beispiel beim herstellen einer Verbindung zu einer DB). Allerdings sehe ich einige Probleme mit Ihnen.
Kurz gesagt, der obige code sieht mehr wie ein "wiederholen" wiederholen", das war bastardized arbeiten eher wie ein timeout. Hier ist, wie würde ich die Struktur einer timeout-Schleife:
Wenn möglich, die asynchrone Verarbeitung verpackt in einem
Task<T>
. Dies bietet das beste aus allen Welten:Task<T>
implementiertIAsyncResult
.Async CTP
; Sie spielen auch gut mitRx
.Wenn Sie benötigen, um ein timeout, dann Rx oder die Async CTP kann vorsehen, dass.
Ich würde werfen Sie einen Blick auf die WaitHandle Klasse. Speziell die ManualResetEvent Klasse, wartet, bis das Objekt gesetzt ist. Sie können auch angeben timeout-Werte für es und überprüfen, ob es gesetzt wurde danach.
Einen Anruf zu
Thread.Sleep
immer ist ein aktives warten vermieden werden sollte.Eine alternative wäre, einen timer zu verwenden. Für einfachere Handhabung, könnte man Kapseln, die in einer Klasse.
Ich in der Regel davon abhalten das auslösen von Ausnahmen.
Ich glaube, Sie sollten AutoResetEvents. Sie arbeiten toll, wenn Sie darauf warten, für einen anderen thread, es zu beenden ist Aufgabe
Beispiel:
Hier ist, wie Sie es tun können, mit
System.Threading.Tasks
:Aber wenn Sie nicht verwenden können, die Aufgaben für einige Grund (wie eine Anforderung .Net 2.0), dann können Sie
ManualResetEvent
wie bereits in JaredPar Antwort oder so etwas wie dieses:Mit der Warte - /Puls-Ansatz nicht explizit, Ereignisse zu erstellen, so brauchen Sie nicht zu kümmern, entsorgen Sie Sie.
Beispiel: