[英]TaskScheduler.Current and TaskScheduler.FromCurrentSynchronizationContext() difference?
I have a task to get products from database, and the 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. 我有一个从数据库获取产品的任务,以及操作一些UI修改的
ContinueWith
操作,因此我遇到了问题,因为Task创建了一个新线程,并且UI修改不是在UI线程中执行的。
I tried to use this fix : 我尝试使用此修复程序:
var currentScheduler = TaskScheduler.Current;
Task.Factory.StartNew(() =>
{
// get products
}).ContinueWith((x) => handleProductsArrived(x.Result, x.Exception), currentScheduler);
but it didn't work at all. 但它根本不起作用。 I check and the
ContinueWith
was not executed in the thread from currentScheduler but in an another. 我检查并且在来自currentScheduler的线程中没有执行
ContinueWith
,而是在另一个中。
I discovered this method : 我发现了这个方法:
Task.Factory.StartNew(() =>
{
// get products
}).ContinueWith((x) => handleProductsArrived(x.Result, x.Exception), TaskScheduler.FromCurrentSynchronizationContext());
and it works. 它的工作原理。 So what's the differences?
那有什么不同呢? Why didn't my first code work?
为什么我的第一个代码不起作用? Thanks!
谢谢!
From the documentation for TaskScheduler.Current
: 从
TaskScheduler.Current
的文档:
When not called from within a task, Current will return the Default scheduler.
如果未在任务中调用,则Current将返回Default调度程序。
Then from the Task Schedulers documentation : 然后从任务计划程序文档 :
The default scheduler for Task Parallel Library and PLINQ uses the .NET Framework ThreadPool to queue and execute work.
任务并行库和PLINQ的默认调度程序使用.NET Framework ThreadPool来排队和执行工作。
So if you use TaskScheduler.Current
when you're not in a task, you'll get a scheduler which uses the thread pool. 因此,如果您在不在任务中时使用
TaskScheduler.Current
,您将获得使用线程池的调度程序。
If you call TaskScheduler.FromCurrentSynchronizationContext()
, you'll get one for the current synchronization context - which in Windows Forms or WPF (when called from a UI thread) is a context which schedules work on the relevant UI thread. 如果您调用
TaskScheduler.FromCurrentSynchronizationContext()
,您将获得当前同步上下文的一个 - 在Windows窗体或WPF中(从UI线程调用时)是一个上下文,用于调度相关UI线程的工作。
So that's why the first code didn't work: it executed your continuation on a thread pool thread. 这就是为什么第一个代码不起作用的原因:它在线程池线程上执行了你的延续。 Your second code executed the continuation on the UI thread.
您的第二个代码在UI线程上执行了延续。
Note that if you can use C# 5 and async/await, all of this is handled much more simply. 需要注意的是,如果你可以使用C#5和异步/的await,所有这一切都是处理更加简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.