Aktualisieren der Benutzeroberfläche aus einem anderen Thread in einer separaten Klasse
Sie stoßen auf das häufige Problem, eine WPF-Benutzeroberfläche aus einem Thread zu aktualisieren, der eine separate Klasse ausführt . Die Benutzeroberfläche friert während der langwierigen Berechnungen ein und Sie müssen den Benutzer über den Fortschritt informieren.
Lösung mit Thread und Ereignissen
Beispielcode:
class MainWindow : Window { private void startCalc() { // Prepare input inputValues input = ...; // Create calculation class and register to its event CalcClass calc = new CalcClass(); calc.ProgressUpdate += (s, e) => Dispatcher.Invoke(() => { /* UI Update */ }); // Start calculation in a separate thread Thread calcthread = new Thread(new ParameterizedThreadStart(calc.testMethod)); calcthread.Start(input); } } class CalcClass { public event EventHandler ProgressUpdate; public void testMethod(object input) { // Raise event to trigger UI update if (ProgressUpdate != null) ProgressUpdate(this, new YourEventArgs(status)); // Notify UI with status updates } }
Alternativen mit .NET 4.5 und höher
Bedenken Sie die Folgende Alternativen mit neueren Funktionen:
Verwenden Aufgaben: Ersetzen Sie den Thread durch eine Aufgabe, um die Thread-Verwaltung zu vereinfachen.
Verwenden von Async/Await: Verschieben Sie die Berechnung, bis sie benötigt wird, indem Sie die UI-Aktualisierungsmethode als asynchron markieren.
Verwendung stark typisierter generischer Ereignisse: Übergeben Sie benutzerdefinierte Datentypen mithilfe stark typisierter Datentypen an das Ereignis generische Ereignisse.
Verbessertes Beispiel mit Erweiterungen:
class MainWindow : Window { Task calcTask = null; // Stores task for later checking void StartCalc() { var calc = PrepareCalc(); calcTask = Task.Run(() => calc.TestMethod(input)); // Start in background } async Task CalcAsync() { var calc = PrepareCalc(); await Task.Run(() => calc.TestMethod(input)); // Await completion } CalcClass PrepareCalc() { // Prepare input and create calc object var calc = new CalcClass(); calc.ProgressUpdate += (s, e) => Dispatcher.Invoke(() => { /* UI Update */ }); return calc; } } class CalcClass { public event EventHandler<EventArgs<YourStatus>> ProgressUpdate; public TestMethod(InputValues input) { // Raise event to trigger UI update ProgressUpdate?.Raise(this, new EventArgs<YourStatus>(status)); // Raise with status } }
Zusätzliche Hinweise:
Das obige ist der detaillierte Inhalt vonWie aktualisiere ich eine WPF-Benutzeroberfläche sicher von einem separaten Thread in einer anderen Klasse?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!