简体   繁体   English

await 不会在原始上下文中恢复

[英]await does not resume on original context

await for some reason does not seem to resume on the calling context.由于某种原因, await似乎没有在调用上下文中恢复。 I'm calling an async method (actually a hierarchy of several async methods).我正在调用一个async方法(实际上是几个async方法的层次结构)。 Things go fine till I finally reaches the DataService which uses RestSharp's ExecuteAsync() .事情 go 很好,直到我最终到达使用 RestSharp 的ExecuteAsync()的 DataService 。 That final call looks like this:最后的调用如下所示:

IRestResponse Response = await rc.ExecuteAsync(request); //rc is a RestClient object

I have debugged it thoroughly and at each level, the following line returns true , even just before calling ExecuteAsync :我已经对其进行了彻底的调试,并且在每个级别,以下行都返回true ,甚至在调用ExecuteAsync之前:

System.Threading.Thread.CurrentThread == System.Windows.Application.Current.Dispatcher.Thread

Only after the ExecuteAsync() returns with server data, the above line becomes false , indicating that the above await did not resume on the calling thread.只有在ExecuteAsync()返回服务器数据后,上面的行才变为false ,表示上面的await没有在调用线程上恢复。 Thereupon, the higher layers that called this async operation and now want to assign returned data to the UI throw the infamous STA thread exception.因此,调用此异步操作并且现在想要将返回的数据分配给 UI 的更高层会抛出臭名昭著的 STA 线程异常。

What am I doing wrong?我究竟做错了什么? I have burnt several hours already and gone through several SO posts and web articles, but this doesn't seem to work.我已经烧了几个小时,并且浏览了几个 SO 帖子和 web 文章,但这似乎不起作用。 I have also added ConfigureAwait(true) to explicitly ask it to resume on calling context, but it didn't.我还添加了ConfigureAwait(true)以明确要求它在调用上下文时恢复,但它没有。

This is a VSTO Word add-in.这是一个 VSTO Word 加载项。 I'm using it with WPF.我将它与 WPF 一起使用。

This is a VSTO Word add-in.这是一个 VSTO Word 加载项。

This is actually the source of the problem.这实际上是问题的根源。

The actual "context" captured by the await is SynchronizationContext.Current (unless it is null , in which case it is TaskScheduler.Current ). await捕获的实际“上下文”是SynchronizationContext.Current (除非它是null ,在这种情况下它是TaskScheduler.Current )。 UI apps like WinForms and WPF provide their own SynchronizationContext , which is how await resumes on the UI thread.像 WinForms 和 WPF 这样的 UI 应用程序提供了自己的SynchronizationContext ,这就是await在 UI 线程上恢复的方式。

Except Office add-ins.除了 Office 加载项。 I'm not sure why, but they do not provide a SynchronizationContext .我不知道为什么,但他们不提供SynchronizationContext So if you want to use await in an Office add-in, you'll need to supply the SynchronizationContext .因此,如果要在 Office 加载项中使用await ,则需要提供SynchronizationContext

I believe a WPF-based Office add-in would be able to do this at the beginning of every async event:我相信基于 WPF 的 Office 加载项将能够在每个async事件开始时执行此操作:

SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());

But I have never actually tried this.但我从未真正尝试过这个。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM