我想实现以下结果 - UI 线程注册我的耗时操作的进度更改事件,然后运行方法“DoOperationAsync()”。然后该操作将报告进度更改,但是:必须在 UI 线程上调用该事件,我在实现时遇到了问题。事件触发,但当我尝试更新 UI 时,我需要使用 Dispatcher,因为事件是从执行操作的线程触发的。我觉得我的库不应该强制开发人员提前思考并在所有地方使用调度程序。
基本上我想做 BackgroundWorker 做的事情。 BackgroundWorker 如何在创建它的线程上触发 ProgressChanged 事件?
最佳答案
如果您使用的是 .NET 4.5,您将可以访问最新版本的 TPL 更改,其中包括 IProgress<T>
接口(interface)及其具体实现 Progress<T>
.该接口(interface)旨在支持两个异步任务之间的进度报告,特别是您需要的后台到 UI 线程报告。
接口(interface)本身很简单,定义 Report(T)
方法作为传递类型进度更新的机制 T
到另一个任务。当您有一些进展需要报告时,您可以调用该操作。如果你想通过百分比进度,你可以通过 0.1
到IProgress<float>
实例报告 10% 的进度。
private async Task BackgroundWorkAsync(IProgress<float> progress)
{
...
progress.Report(0.1); // 10%
...
progress.Report(1.0); // 100%
}
UI 线程应该创建具体的 Progress<T>
实例并将其传递到后台任务的范围内。 Progress<T>
提供一个 ProgressChanged
您可以订阅的事件,但通常您将一个操作传递给构造函数,以便在每次更新进度时调用:
var progress = new Progress(value => // set progress bar);
await this.BackgroundWorkAsync(progress);
这是一个粗略的例子,但它展示了 Progress<T>
的神奇之处根据上下文同步回调,在本例中为 UI 线程。
关于c# - 在 UI 线程上报告后台线程进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18016614/