任何情况下使用Task.ContinueWith(..., TaskScheduler.FromCurrentSynchronizationContext())时不会在UI线程上运行吗?

9

我们发现了一些奇怪的事情,代码看起来像这样:

var task = new Task(...); // run in the background, do something lengthy work
task.ContinueWith(..., TaskScheduler.FromCurrentSynchronizationContext());
task.Start();

第二个任务调用了一个事件,该事件尝试更新GUI,我们遇到了可怕的跨线程异常。

从第二个任务中的方法检查 Thread.CurrentThread.ManagedThreadId 指示它实际上并没有在UI线程上运行。

生成任务的代码正在UI线程上运行。

是否存在任何可能导致出错的情况?


1
为什么直接创建任务而不是运行Task.StartNew? - Panagiotis Kanavos
@PanagiotisKanavos,这样做可能有合理的原因(请参见http://blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx),但这与问题无关。 - Matt Smith
嗯,我无法重现这个问题,也没有遇到过这种情况,除非在第一次调用创建任务时并没有真正在 UI 线程中进行。 - Panagiotis Kanavos
我会首先在调试器中检查TaskScheduler.FromCurrentSynchronizationContext返回的内容。你这样做时会发现什么? - usr
@Lasse,你找到这个问题的原因或解决方案了吗? - shaibee
是的,忘记将答案标记为已接受。问题出在 .net 4.0 和空同步上下文上,因此在某些时候会创建一个新的上下文,与 GUI 线程无关。 - Lasse V. Karlsen
1个回答

4
假设您正在使用.NET 4.0,存在一个错误,即主线程上的 System.Threading.SynchronizationContext.Current 可能会变为 null,并且您将遇到此问题。如果您可以轻松地重现该问题,则首先要检查的是在调用 TaskScheduler.FromCurrentSynchronizationContext()SynchronizationContext.Current 是否为 null。
请参阅此问题的详细信息:SynchronizationContext.Current is null in Continuation on the main UI thread 该错误已在.NET 4.5中修复。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接