从工作线程调用时的TaskScheduler.FromCurrentSynchronizationContext异常

时间:2014-03-05 10:36:51

标签: c# .net c#-4.0 task-parallel-library

不太清楚这里发生了什么 -

这段代码导致问题,因为它首先从主线程调用(在VS的任务视图中验证)并安排任务,但是在UpdateSearchCache中设置断点时我们现在在工人线程 - 不再是主要的!

从那里调用的后续UI代码失败,因为它们在工作线程上执行。

不是指定调度程序的全部意义吗?我错过了什么?

启动我们的应用程序时会调用此代码。它是从我们的PRISM应用程序的Bootstrapper调用并在 MainThread 上运行。

启动任务时SynchronizationContext.Current不为空。

var currentScheduler = TaskScheduler.FromCurrentSynchronizationContext();
var ctx = SynchronizationContext.Current;
if (ctx == null)
    throw new NullReferenceException();

Task.Factory
    .StartNew(
        () =>
            SearchHelper.CacheSearchResults(_service.GetData())
    .ContinueWith(result => UpdateCache(result.Result), currentScheduler);

2 个答案:

答案 0 :(得分:1)

当调用线程上没有同步上下文时,

TaskScheduler.FromCurrentSynchronizationContext会抛出InvalidOperationException,即SynchronizationContext.Current返回null。

答案 1 :(得分:1)

这里真的很奇怪。尝试以下方法。这是一种解决方法,但它也可能有助于诊断问题:

var dispatcher = Dispatcher.CurrentDispatcher;
Debug.Assert(dispatcher == Application.Current.Dispatcher);

Task.Factory
    .StartNew(
        () => SearchHelper.CacheSearchResults(_service.GetData()))
    .ContinueWith(result => 
    { 
        // is the app's dispatcher still the same?

        Debug.Assert(dispatcher == Application.Current.Dispatcher);

        // explicitly use Dispatcher.BeginInvoke, that's what
        // DispatcherSynchronizationContext does behind the scene

        Application.Current.Dispatcher.BeginInvoke(new Action(
            () => UpdateCache(result.Result)));

    }, TaskContinuationOptions.ExecuteSynchronously);