我有一个从数据库获取产品的任务,以及操作一些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());而且它是有效的。那么有什么不同呢?为什么我的第一个代码不能工作?谢谢!
发布于 2013-04-16 16:29:43
来自TaskScheduler.Current的文档
当不是从任务内部调用时,Current将返回默认调度程序。
然后从Task Schedulers documentation
是任务并行库的默认调度程序,它使用.NET框架ThreadPool来排队和执行工作。
因此,如果您在不在任务中时使用TaskScheduler.Current,您将获得一个使用线程池的调度器。
如果你调用TaskScheduler.FromCurrentSynchronizationContext(),你会得到一个当前的synchronization context -在Windows Forms或者WPF中(当从UI线程调用时)是一个在相关UI线程上调度工作的上下文。
这就是第一段代码不起作用的原因:它在线程池线程上执行延续。您的第二个代码在UI线程上执行了continuation。
请注意,如果您可以使用C# 5和async/await,所有这些操作都会简单得多。
https://stackoverflow.com/questions/16032102
复制相似问题