【问题标题】:How can I get the continuation after an await to execute on the same thread?在等待在同一个线程上执行后如何获得继续?
【发布时间】:2012-10-06 09:05:09
【问题描述】:

正如我最近发现的那样,在没有同步上下文的情况下执行await 可能会导致等待后的代码在不同的线程上执行。

我目前在 VSTO 办公室插件中遇到奇怪行为的问题,我认为这可能是这种行为的结果。在处理 Office 应用程序引发的事件时,没有适当的同步上下文(除非我创建了一个表单,这将创建一个同步上下文)。

我的问题是创建表单是否是确保我拥有同步上下文的最佳/最有效方式,或者是否有更简单的方式来做到这一点。

【问题讨论】:

  • 在这种情况下不使用await不是更容易吗?如果您使用的 API 仅是异步的,您可以通过使用 TaskResultWait() 来实现。
  • @svick:我猜你的意思是,如果我希望 await 在同一个线程上返回,那么这实际上是“同步”行为。嗯……是的,我想是的。 叹息。老实说,我对这些东西有点迷茫。

标签: c# async-await c#-5.0


【解决方案1】:

Office 应用确实在 STA 上下文中调用它们的事件,但它们没有提供适当的 SynchronizationContext

解决此问题的最简单方法在我的博客SynchronizationContext Odds and Ends 中进行了解释,我在其中简要描述了我在为我的文章进行研究时发现的一些杂项事情,但这些事情还不够重要,不能包括在内。要解决此问题,请在每个事件开始时执行以下操作:

SynchronizationContext.SetSynchronizationContext(
    new WindowsFormsSynchronizationContext());

此后的任何awaits 都应在 STA 线程上恢复。

【讨论】:

【解决方案2】:

您可能想查看this article,它描述了如何在没有消息泵的情况下设置 SynchronizationContext。请注意,这仅在您希望有其他要等待的工作(排队多个回调)时才真正有用。如果您一次只等待一件事,您的代码也可能只是同步运行,因为您没有'与您的空闲时间无关,例如运行消息泵。

【讨论】:

    猜你喜欢
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 2018-05-19
    • 2015-04-09
    • 1970-01-01
    相关资源
    最近更新 更多