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

c#

await由于某种原因,似乎没有在调用上下文中恢复。我正在调用一个async方法(实际上是几个async方法的层次结构)。一切顺利,直到我最终到达使用 RestSharp 的ExecuteAsync(). 最后的调用如下所示:

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

我已经彻底调试了它,在每个级别true,甚至在调用之前,以下行都会返回ExecuteAsync

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

只有在ExecuteAsync()返回服务器数据后,上面的行才变成false,表明上面await没有在调用线程上恢复。因此,调用此异步操作并现在想要将返回的数据分配给 UI 的更高层抛出臭名昭著的 STA 线程异常。

我究竟做错了什么?我已经烧了几个小时并浏览了几篇 SO 帖子和网络文章,但这似乎不起作用。我还添加ConfigureAwait(true)了明确要求它在调用上下文时恢复,但它没有。

这是一个 VSTO Word 插件。我将它与 WPF 一起使用。

回答

这是一个 VSTO Word 插件。

这实际上是问题的根源。

awaitis捕获的实际“上下文” SynchronizationContext.Current(除非它是null,在这种情况下它是TaskScheduler.Current)。像 WinForms 和 WPF 这样的 UI 应用程序提供了它们自己的SynchronizationContext,这就是await在 UI 线程上恢复的方式。

除了 Office 加载项。我不确定为什么,但他们没有提供SynchronizationContext. 因此,如果您想await在 Office 加载项中使用,则需要提供SynchronizationContext.

我相信基于 WPF 的 Office 加载项能够在每个async事件开始时执行此操作:

SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());

但我从来没有真正尝试过这个。:)


以上是await不会在原始上下文中恢复的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>