TaskScheduler.Current和TaskScheduler.FromCurrentSynchronizationContext()的区别?

时间:2013-04-16 08:23:32

标签: c# task scheduler

我有从数据库获取产品的任务,以及操作某些UI修改的ContinueWith操作,因此我遇到了问题,因为Task创建了一个新线程,并且UI修改不在UI中执行线程。

我尝试使用此修复程序:

var currentScheduler = TaskScheduler.Current;

Task.Factory.StartNew(() =>
{    
    // get products   
}).ContinueWith((x) => handleProductsArrived(x.Result, x.Exception), currentScheduler);

但它根本不起作用。我检查并且ContinueWith没有在currentScheduler的线程中执行,而是在另一个线程中执行。

我发现了这种方法:

Task.Factory.StartNew(() =>
{
    // get products
}).ContinueWith((x) => handleProductsArrived(x.Result, x.Exception), TaskScheduler.FromCurrentSynchronizationContext());

它有效。那有什么不同呢?为什么我的第一个代码不起作用? 谢谢!

1 个答案:

答案 0 :(得分:15)

来自TaskScheduler.Current的文档:

  

如果未在任务中调用,则Current将返回Default调度程序。

然后从Task Schedulers documentation

  

任务并行库和PLINQ的默认调度程序使用.NET Framework ThreadPool来排队和执行工作。

因此,如果您在不在任务中时使用TaskScheduler.Current,您将获得一个使用线程池的调度程序。

如果您致电TaskScheduler.FromCurrentSynchronizationContext(),您将获得当前synchronization context的一个 - 在Windows窗体或WPF中(从UI线程调用时)是在相关UI上安排工作的上下文线程。

这就是为什么第一个代码不起作用的原因:它在线程池线程上执行了你的延续。你的第二个代码在UI线程上执行了延续。

请注意,如果你可以使用C#5和async / await,那么所有这些都可以更简单地处理很多