我有一个从数据库中获取产品的任务,以及操作一些 UI 修改的 ContinueWith
操作,因此我遇到了一个问题,因为任务创建了一个新线程,并且没有执行 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());
并且有效。那么有什么区别呢?为什么我的第一个代码不起作用? 谢谢!
最佳答案
来自 TaskScheduler.Current
的文档:
When not called from within a task, Current will return the Default scheduler.
然后从Task Schedulers documentation :
The default scheduler for Task Parallel Library and PLINQ uses the .NET Framework ThreadPool to queue and execute work.
因此,如果您在不执行任务时使用 TaskScheduler.Current
,您将获得一个使用线程池的调度程序。
如果您调用 TaskScheduler.FromCurrentSynchronizationContext()
,您将获得当前 synchronization context 的一个- 在 Windows 窗体或 WPF 中(当从 UI 线程调用时)是一个上下文,用于安排相关 UI 线程上的工作。
这就是第一个代码不起作用的原因:它在线程池线程上执行您的延续。您的第二个代码在 UI 线程上执行了延续。
请注意,如果您可以使用 C# 5 和 async/await,那么所有这些处理起来都很多更简单。
关于c# - TaskScheduler.Current 和 TaskScheduler.FromCurrentSynchronizationContext() 的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16032102/