【发布时间】:2018-07-15 11:04:43
【问题描述】:
我一直在使用Progress<T>,想知道是否可以将其替换为Action<T>。
在下面的代码中,使用它们中的每一个来报告进度,即ReportWithProgress() 或ReportWithAction(),对我没有任何明显的影响。 progressBar1 是如何增加的,字符串是如何写在输出窗口上的,它们看起来都一样。
// WinForm application with progressBar1
private void HeavyIO()
{
Thread.Sleep(20); // assume heavy IO
}
private async Task ReportWithProgress()
{
IProgress<int> p = new Progress<int>(i => progressBar1.Value = i);
for (int i = 0; i <= 100; i++)
{
await Task.Run(() => HeavyIO());
Console.WriteLine("Progress : " + i);
p.Report(i);
}
}
private async Task ReportWithAction()
{
var a = new Action<int>(i => progressBar1.Value = i);
for (int i = 0; i <= 100; i++)
{
await Task.Run(() => HeavyIO());
Console.WriteLine("Action : " + i);
a(i);
}
}
但是Progress<T> 不可能是轮子的再发明。实施它应该是有原因的。谷歌搜索“c# Progress vs Action”并没有给我太多帮助。 Progress 与 Action 有何不同?
【问题讨论】:
-
我建议您将
HeavyIO更改为async Task HeavyIO() { await Task.Delay(20); }以便至少您正在调用一个任务 -
Progress<T>在构造它的上下文中调用该操作,这使您可以与 UI 交互而无需烦人的调用代码。 -
您在
Progress的文档中找到了哪些信息,为什么无法回答您的问题? -
从不同的线程调用
progressBar1.Value = i会导致可怕的"cross-thread operation not valid" 异常。
标签: c# generics delegates progress