支持.NET 4.0“任务并行库”中的进度报告和增量结果
-
20-09-2019 - |
解决方案
此示例更新进度条:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
class SimpleProgressBar : Form
{
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.Run(new SimpleProgressBar());
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
int iterations = 100;
ProgressBar pb = new ProgressBar();
pb.Maximum = iterations;
pb.Dock = DockStyle.Fill;
Controls.Add(pb);
Task.ContinueWith(delegate
{
Parallel.For(0, iterations, i =>
{
Thread.SpinWait(50000000); // do work here
BeginInvoke((Action)delegate { pb.Value++; });
});
});
}
}
其他提示
这是我的首要搜索结果中的一个,仍然在Task Parallel Library
进展没有如在这里...
今天我只是碰到TPL来到这里是因为我想开发新的多线程应用程序,但没有使用BackgroundWorker
(因为我也读到了漂亮的代码之前任务的地方)
我编译从@Stephen克利答案的例子,他的链接,查找进度相当复杂,和其他一些网站。
这是很简单的例子,怎么做的进度和已完成与UI线程安全的方式:
TaskScheduler currentTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task<string>.Factory.StartNew(() =>
{
// loop for about 10s with 10ms step
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(10);
Task.Factory.StartNew(() =>
{
// this is a task created each time you want to update to the UI thread.
this.Text = i.ToString();
}, CancellationToken.None, TaskCreationOptions.None, currentTaskScheduler);
}
return "Finished!";
})
.ContinueWith(t =>
{
// this is a new task will be run after the main task complete!
this.Text += " " + t.Result;
}, currentTaskScheduler);
代码将显示1至1000 10秒内,然后追加一个“完成”!串在Windows窗体的标题栏。你可以看到的TaskScheduler是创建UI线程安全更新,因为我觉得计划任务要在主线程运行取巧的办法。
没有像BackgroundWorker那样的内置支持。
可以直接使用SynchronizationContext;这里有一个很棒的视频: http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video=TasksAndThreadAffinity.wmv
作者在该视频中提出了两种解决方案:一个使用 SynchronizationContext,另一个使用 Task Continuations。对于您的问题,延续将不起作用,但 SynchronizationContext 方法可以正常工作。
附:如果您正在创建可重用的代码,那么当您捕获 SynchronizationContext.Current 时,您应该测试 null 并(如果为 null)使用默认构造的 SynchronizationContext。
更新: :我已经为此发布了代码 在我的博客上. 。我的解决方案实际上是基于 Task
由 a 安排回 UI 线程 TaskScheduler
它使用 SynchronizationContext
下。与已接受的答案不同,此解决方案适用于 WPF 和 Windows 窗体。
在TPL没有特别朝向UI支持导向,可以(仍然)使用一个BackgroundWorker为该。作为发送或处理的中间结果,也有新collectionclasses(ConcurrentQueue)来支持这一点。