Hem*_*ant 15 c# .net-4.0 task-parallel-library
我知道任务并行库仍然处于测试阶段,可能会有更少的可用资源,但是从我读过的内容来看,库为任务调度,异常处理和取消提供了非常特殊的处理.
但我没有找到任何关于进度报告和从任务发送增量结果的引用.这两件事似乎太重要了,不容忽视.您能否介绍如何在任务并行库中处理这些内容或参考一些解释它们的文章?
此示例更新进度条:
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++; });
});
});
}
}
Run Code Online (Sandbox Code Playgroud)
这是我最热门的搜索结果之一,仍然没有在Task Parallel Library这里取得进展的例子......
今天我刚遇到TPL,因为我想开发新的多线程应用程序,但没有使用BackgroundWorker(因为我以前用好的代码读过任务的任务)
我从@Stephen Cleary回答编译示例,他的链接相当复杂,以寻找进展,以及其他一些网站.
这是如何使用UI线程安全方式执行Progress和Completed的非常简单的示例:
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);
Run Code Online (Sandbox Code Playgroud)
代码将在10秒内显示1到1000,然后附加"完成!" 窗体中的字符串形式标题栏.您可以看到TaskScheduler是创建UI线程安全更新的棘手方法,因为我认为任务计划在主线程上运行.
没有像BackgroundWorker那样的内置支持.
您可以直接使用SynchronizationContext; 这里有一个很棒的视频:http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch? video = TasksAndThreadAffinity.wmv
作者在此视频中开发了两个解决方案:一个使用SynchronizationContext,另一个使用Task Continuations.对于您的问题,continuation将不起作用,但SynchronizationContext方法将正常工作.
PS如果您正在创建可重用的代码,那么当您捕获SynchronizationContext.Current时,您应该测试null并且(如果它为null)使用默认构造的SynchronizationContext.
更新:我在我的博客上发布了此代码.我的解决方案实际上是基于Task一个TaskScheduler使用SynchronizationContext底层调度回到UI线程的解决方案.与接受的答案不同,此解决方案适用于WPF和Windows窗体.
| 归档时间: |
|
| 查看次数: |
8552 次 |
| 最近记录: |