從單獨類別中的另一個執行緒更新 UI
您遇到從執行單獨類別的執行緒更新 WPF UI 的常見問題。 UI 在冗長的計算過程中凍結,您需要通知使用者進度。
使用執行緒和事件的解決方案
範例程式碼:
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 } }
.NET 4.5及更高版本的替代方案
考慮以下使用較新的替代方案功能:
使用任務:用任務取代執行緒以簡化執行緒管理。
使用非同步/等待:延遲計算直到它需要透過將 UI 更新方法標記為非同步來實現。
強烈使用類型化通用事件: 使用強型別通用事件將自訂資料型別傳遞給事件。
有擴充的改進範例:
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 } }
其他注意:
以上是如何從不同類中的單獨執行緒安全地更新 WPF UI?的詳細內容。更多資訊請關注PHP中文網其他相關文章!