如何从另一个类中的后台任务更新 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中文网其他相关文章!