Update UI von mehreren worker-threads (.NET)
Habe ich ein pet-Projekt, an dem ich arbeite, hat mehrere worker-threads. Ausgabe alles um die Konsole ist immer schwer zu Folgen, so dass ich bei der Entwicklung einer Benutzeroberfläche, haben Sie eine Ausgabe-Bereich, pro-thread. Ich möchte wissen, der beste Weg für die Fäden, um das senden von updates an der Benutzeroberfläche. Ich habe zwei Ideen:
1) jeder thread einen "DataUpdated" - flag, wenn neue Daten verfügbar sind, und die UI in regelmäßigen Abständen prüfen, ob neue Daten.
2) Erstellen, jeden thread mit einem callback zu einem UI Update (...) - Methode aufgerufen wird, wenn neue Daten verfügbar sind.
Ich bin derzeit Neigung zu (2) aus zwei Gründen: mir gefällt die Idee der "überprüfung" jeden thread, und da dies mein erstes Multithreading-Anwendung und (2) scheint einfacher, als es wahrscheinlich ist. Ich will wissen:
- Welche option vorzuziehen ist, im Hinblick auf Einfachheit und Effizienz?
- Haben Sie irgendwelche Tipps für die Umsetzung (2) oder etwas ähnliches (D. H. mehr event-driven)?
InformationsquelleAutor iandisme | 2010-01-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie einfach implementieren, (2) durch die Schaffung von BackgroundWorker Komponenten und macht die Arbeit in Ihrer DoWork-Handler:
Jeder BackgroundWorker können die Fortschritte an den UI-thread durch Aufruf von ReportProgress: dies ist zwar in Erster Linie für die Berichterstattung über die Fortschritte auf einem begrenzten Prozess, das ist nicht zwingend erforderlich-Sie übergeben können Ihre eigenen Daten, als auch, wenn das, was Ihr UI-update erfordert. Rufen Sie ReportProgress aus deiner DoWork-Ereignishandler.
Die nette Sache über BackgroundWorker ist, dass es kümmert sich um eine Menge von unordentlichen cross-threading-details für Sie. Es entspricht ebenfalls der event-driven-Modell von updates, die Sie (zu Recht) lieber explizite Rückrufe.
Diese Arbeit im Compact framework(3.5).
InformationsquelleAutor itowlson
Ich vote für #2, aber mit BackgroundWorkers anstelle von System.Threading.Threads.
InformationsquelleAutor Austin Salonen
In den meisten Fällen die einfachste Sache zu tun wäre, um die BackgroundWorker-Komponente, wie vorgeschlagen, in itowlson Antwort, und ich würde dringend vorschlagen, diesen Ansatz verwenden, wenn möglich. Wenn, aus irgendeinem Grund, Sie nicht verwenden können, eine BackgroundWorker-Komponente für Ihre Zwecke, wie zum Beispiel, wenn Sie die Entwicklung mit .Net 1.1 (Huch!) oder mit dem compact framework, dann müssen Sie möglicherweise einen alternativen Ansatz:
Mit Winform-controls, die Sie haben zu vermeiden, ändern der Steuerelemente auf jedem anderen thread als dem thread, der ursprünglich das Steuerelement erstellt wurde. Die BackgroundWorker-Komponente übernimmt dies für Sie, aber wenn Sie nicht verwenden, dann Sie können und sollten die InvokeRequired-Eigenschaft und rufen Sie die Methode auf dem System gefunden.Windows.Formen.Control-Klasse. Unten ist ein Beispiel für die Verwendung dieser Eigenschaft und Methode:
InformationsquelleAutor Dr. Wily's Apprentice
Können Sie Ihre worker-threads, die Ereignisse auslösen und den main-UI-thread hinzufügen von Ereignishandlern. Sie müssen vorsichtig sein, du bist nicht anheben zu viele Ereignisse, als könnte es hässlich werden, wenn Ihr worker-threads die mehrere Ereignisse pro Sekunde.
Diese Artikel gibt einen schnellen überblick.
InformationsquelleAutor TLiebe
Das bevorzugte Verfahren für die Implementierung von multithreading in Ihrer Anwendung zu verwenden, die BackgroundWorker Komponente. Die BackgroundWorker-Komponente verwendet ein Ereignisgesteuertes Modell für multithreading. Der worker-thread läuft das DoWork-Ereignishandler, und der thread, der erstellt Ihr steuert, läuft das ProgressChanged und RunWorkerCompleted-Ereignishandler.
Wenn Sie aktualisieren Sie Ihre UI-Steuerelemente in der ProgressChanged-Event-Handler, Sie werden automatisch aktualisiert und auf den main-thread, die verhindern, dass Sie immer crossthread Ausnahmen.
Aussehen hier für ein Beispiel zur Verwendung der backgroundworker-Klasse.
InformationsquelleAutor Mez
Wenn Sie Ihre eigenen threads (nicht BackgroundWorker oder ThreadPool-threads) können Sie eine callback-Methode aus dem main thread aufgerufen, aus dem worker-thread. Diese können Sie auch Argumente an die callback-und auch einen Wert zurückgeben (wie ein go/no-go-flag). In der callback-aktualisieren Sie die Benutzeroberfläche über das target-control Dispatcher:
InformationsquelleAutor Ed Power