如何從另一個類別中的後台任務更新 UI
後台任務可以執行冗長的操作而不凍結 UI。但是,從這些任務更新 UI 需要跨執行緒機制。本文介紹如何使用事件和委託來完成此操作。
使用事件和委託
要從後台執行緒更新 UI,您可以使用事件和委託。當特定事件發生時會引發事件,允許訂閱者執行預先定義的程式碼作為回應。委託代表可以在單獨執行緒中呼叫的方法。
基於事件的方法
在這種方法中,當 UI 需要時,後台執行緒會引發一個事件。已更新。主執行緒訂閱該事件並執行對應的 UI 更新程式碼。以下是一個範例:
class MainWindow : Window { private void startCalc() { // ... CalcClass calc = new CalcClass(); calc.ProgressUpdate += (s, e) => { Dispatcher.Invoke((Action)delegate() { /* Update UI */ }); }; Thread calcthread = new Thread(new ParameterizedThreadStart(calc.testMethod)); calcthread.Start(input); } } class CalcClass { public event EventHandler ProgressUpdate; public void testMethod(object input) { // ... if (ProgressUpdate != null) ProgressUpdate(this, new YourEventArgs(status)); // ... } }
基於任務的方法(C# 4.5 及更高版本)
另一個選擇是使用代表非同步操作的任務。可以使用 Task.Run 方法建立任務,它們提供了一種在單獨執行緒中執行程式碼的乾淨方法。
class MainWindow : Window { Task calcTask = null; void buttonStartCalc_Clicked(object sender, EventArgs e) { StartCalc(); } async void buttonDoCalc_Clicked(object sender, EventArgs e) { await CalcAsync(); } void StartCalc() { var calc = PrepareCalc(); calcTask = Task.Run(() => calc.TestMethod(input)); } Task CalcAsync() { var calc = PrepareCalc(); return Task.Run(() => calc.TestMethod(input)); } // ... } class CalcClass { public event EventHandler<EventArgs<YourStatus>> ProgressUpdate; public TestMethod(InputValues input) { // ... ProgressUpdate.Raise(this, status); // ... } }
結論
兩個事件-基於方法和基於任務的方法可用於從後台執行緒更新 UI。基於事件的方法更簡單,但基於任務的方法提供更好的控制和錯誤處理。選擇最適合您特定要求的方法。
以上是如何從另一個類別的後台執行緒安全地更新 UI?的詳細內容。更多資訊請關注PHP中文網其他相關文章!