2017-08-31 1 views
0

Hier ist ein Szenario, es ist eine Winforms-Anwendung, wo ich eine Sammlung von Prozessen habe ich nacheinander in einer For-Schleife im DoWork ausgeführt Ereignis der Backgroundworker-Klasse. Und ich rufe ReportProgress() periodisch in der for-Schleife auf, um UI zu aktualisieren.Wie kann ich überprüfen, ob zuvor ProgressChanged in DoWork-Ereignis in c ausgeführt wurde #

Jetzt, wenn ich ReportProgress() aufrufe, triggert das ProgressChanged-Ereignis, wo ich den Code habe, um die UI mit allen Nachrichten zu aktualisieren, die ich zuvor in DoWork eingestellt habe. Aber da dies in einem separaten Thread ausgeführt wird, geht das Steuerelement in DoWork parallel, aber ich möchte die for-Schleife für einige Zeit bis zum zuvor ausgeführten ProgressChanged-Ereignis halten/warten.

Momentan rufe ich Thread.Sleep (1000) in for-Schleife auf, bevor ich irgendeine Operation darin ausführe (wie den nächsten Prozess abholen und ausführen) und dieser Code gibt mir die gewünschte Ausgabe. Also wollte ich nur prüfen, ob es eine alternative Lösung gibt (ich benutze stattdessen Thread.Sleep nicht) Ich kann die for-Schleife überprüfen/warten, bis das zuvor ausgeführte ProgressChanged-Ereignis seinen Job beendet hat, und nur dann gehe ich weiter Führen Sie den nächsten Prozess aus der Auflistung in for-Schleife aus.

+1

Tun Sie das einfach nicht. Wechseln Sie häufiger zum Aufruf von ReportProgress(), um Ihre Nachrichten zu pumpen, um den Benutzer zu verwenden, aber dieser Mechanismus war nie dazu gedacht, die Dinge in perfekter Synchronisation zu halten. –

+1

Verwenden Sie ein AutoResetEvent, um es zu synchronisieren. Rufen Sie die Methode Set() in einem finally-Block im Ereignishandler und WaitOne() nach dem ReportProgress-Aufruf auf. –

+0

@JoelCoehoorn Ich kann das tun, aber ich bin einige Nachrichten in einem Stringbuilder-Objekt in DoWork anhängen und im ProgressChanged-Ereignis verwenden. Also, während das Objekt zur Aktualisierung von Ui konsumiert wird, wird es in DoWork parallel aktualisiert. Um dies zu vermeiden, wollte ich eine Verzögerung in DoWork einführen, Calling ReportProgress wird sehr oft das stringbuilder-Objekt verwenden und aktualisieren, da es die Ausgabe nicht in der richtigen Reihenfolge anzeigt. –

Antwort

1

Ohne die Probleme mit Ihrem Gesamtdesign anzugehen, gehen Sie wie folgt vor: semaphore. Das grundlegendste Beispiel wäre:

static Semaphore _semaphore = new Semaphore(0,1); 
WorkStatus _workStatus; 

void DoWork() 
{ 
    _semaphore.WaitOne(); 
    try 
    { 
     _workStatus = Foo(); //Only one thread will be able to execute this at a time 
    } 
    finally 
    { 
     _semaphore.Release(); 
    } 
} 

void HandleProgressChanged() 
{ 
    _semaphore.WaitOne(); //Wait for any DoWork threads to finish 
    try 
    { 
     DisplayProgress(_workStatus); 
    } 
    finally 
    { 
     _semaphore.Release(); 
    } 
    Task.Run(DoWork); 
} 
+0

Ich bin neu im Semaphore-Konzept. Aber diese Lösung sieht gut aus. Nur eine Sache möchte ich wissen: Kann dies mit dem Backgroundworker-Kurs zusammenhängen? –

+1

Ja, das macht nichts. Welcher C# -Code auf dieses Semaphor zugreifen kann, kann es auf diese Weise verwenden. –

Verwandte Themen