[英]TaskScheduler.FromCurrentSynchronizationContext exception when called from worker thread
Not quite sure what's going on here - 不太确定这里发生了什么-
This bit of code is causing issues as it is first called from the Main thread (verified in Task view in VS) and scheduling the tasks, however when setting a breakpoint in UpdateSearchCache
we're now in the worker thread - no longer main! 这段代码引起了问题,因为它首先是从主线程中调用的(在VS的“任务”视图中已验证)并计划了任务,但是在UpdateSearchCache
设置断点时,我们现在位于工作线程中-不再是主线程!
Subsequent pieces of UI code being called from there fail as they're executed on the worker thread. 从那里调用的后续UI代码片段在工作线程上执行时失败。
Isn't that the whole point of specifying the scheduler? 这不是指定调度程序的全部目的吗? What am I missing? 我想念什么?
This code is called when starting our app. 启动我们的应用程序时会调用此代码。 It's called from the Bootstrapper of our PRISM app and running on the MainThread . 它是从我们PRISM应用程序的Bootstrapper中调用的,并在MainThread上运行。
The SynchronizationContext.Current
is NOT null when the Task is started. 启动Task时, SynchronizationContext.Current
不为null。
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);
当调用线程上没有同步上下文时, TaskScheduler.FromCurrentSynchronizationContext
引发InvalidOperationException
,即SynchronizationContext.Current
返回null。
Something really weird is going on here. 这里确实发生了一些奇怪的事情。 Try the following approach. 请尝试以下方法。 It's a workaround, but it also may help to diagnose the problem: 这是一种解决方法,但也可能有助于诊断问题:
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.