c# - 在 UI 线程上报告后台线程进度

标签 c# .net multithreading

我想实现以下结果 - UI 线程注册我的耗时操作的进度更改事件,然后运行方法“DoOperationAsync()”。然后该操作将报告进度更改,但是:必须在 UI 线程上调用该事件,我在实现时遇到了问题。事件触发,但当我尝试更新 UI 时,我需要使用 Dispatcher,因为事件是从执行操作的线程触发的。我觉得我的库不应该强制开发人员提前思考并在所有地方使用调度程序。

基本上我想做 BackgroundWorker 做的事情。 BackgroundWorker 如何在创建它的线程上触发 ProgressChanged 事件?

最佳答案

如果您使用的是 .NET 4.5,您将可以访问最新版本的 TPL 更改,其中包括 IProgress<T> 接口(interface)及其具体实现 Progress<T> .该接口(interface)旨在支持两个异步任务之间的进度报告,特别是您需要的后台到 UI 线程报告。

接口(interface)本身很简单,定义 Report(T) 方法作为传递类型进度更新的机制 T到另一个任务。当您有一些进展需要报告时,您可以调用该操作。如果你想通过百分比进度,你可以通过 0.1IProgress<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/

相关文章:

c# - 我如何确保在 .NET 中正确处理对象?

.net - SignalR 卡在外键上

c - Linux C 中的多线程队列

c# - asp.net CORE 迁移生成空

.net - Visual Studio 2010 - 本地历史功能?

c# - 'do...while' 与 'while'

Java - 为什么这个基本的 ticking 类会占用这么多 cpu?

Java RMI 和线程同步问题

c# - 在 c# 中反转字符串中的单词,保持空格数相同

c# - Infragistics UltraGrid 中复选框的检查更改会引发哪个事件?