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

Dah*_*vos 9 c# scheduler task

我有一个从数据库中获取产品的任务 ContinueWith action that operate some UI modification, therefore I had a problem because the Task create a new thread, and the UI modification was executed not in the UI Thread.

我尝试使用此修复程序:

var currentScheduler = TaskScheduler.Current;

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

但它根本不起作用.我查了一下ContinueWith没有在currentScheduler的线程中执行,而是在另一个中执行.

我发现了这个方法:

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

它的工作原理.那有什么不同呢?为什么我的第一个代码不起作用?谢谢!

Jon*_*eet 17

从以下文档TaskScheduler.Current:

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

然后从任务计划程序文档:

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

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

如果你打电话TaskScheduler.FromCurrentSynchronizationContext(),你将得到一个当前同步上下文 - 在Windows窗体或WPF(从UI线程调用时)是一个上下文调度相关UI线程的工作.

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

需要注意的是,如果你可以使用C#5和异步/的await,所有这一切都是处理很多更简单.