【问题标题】:Reuse an awaiting thread重用等待线程
【发布时间】:2013-11-27 14:21:37
【问题描述】:

所以,众所周知,asp.NET、WPF 和 WinRT 等框架会为您管理一个或多个线程。在 asp.NET 中,框架汇集了一组线程,这些线程从队列中获取请求并处理它们。在 WPF 中,框架为您管理 UI 线程,该线程从消息泵中获取消息。

这可以通过简单的生产者/消费者方法来实现,其中消费线程执行while(true) 循环,从队列中获取消息并使用消息处理程序(用户代码)来执行它们。很简单。你可以在这里找到一个基本的实现:https://stackoverflow.com/a/5828863/857807

通过引入 async/await 语义,您可以将 CPU/IO 密集型工作委托给其他线程,并让(例如)UI 线程保持响应。这意味着 UI 线程将继续从泵中获取消息。

我的问题是:从上述基本实现开始,消费者将如何实现呢?您怎么知道消息处理程序正在异步等待另一个线程完成并因此从队列中获取另一条消息?我确定我在这里遗漏了一些重要的东西。

【问题讨论】:

  • 您是在问 WPF/etc UI 线程是如何做到这一点的,还是您自己如何在特定线程上做到这一点?
  • 我确信框架的实际实现对我来说有点矫枉过正,我只是想知道它的要点。我不是想自己实现它,但出于好奇,我想知道如果我愿意的话我会怎么做。

标签: c# .net multithreading task-parallel-library async-await


【解决方案1】:

关键是当async 方法在await 中产生时,它实际上返回 给它的调用者。所以,从主循环来看,方法已经完成了。

稍后,当等待操作完成时,它会将 async 方法的其余部分安排到捕获的上下文中。在您提到的情况下(ASP.NET / WPF / WinRT),上下文是SynchronizationContext。在 UI 框架(WPF / WinRT / WinForms / 等)中,SynchronizationContext 绑定到消息队列。

因此,如果您想要一个与async 兼容的“主循环”,则需要实现一个自定义的SynchronizationContext,以允许将委托安排回该主循环。

更多信息:

【讨论】:

  • 很好的解释,谢谢!我完全忘记了消息处理程序通常是async void 方法!这自然意味着该方法将在遇到第一个 await 关键字时返回,从而使消费者继续下一条消息。现在这一切似乎都很明显 * 。 *
  • @dcastro 不管void还是非void,它都会这样做。也就是说,您几乎不应该拥有 async void 方法,除非您需要让它成为事件的处理程序。
  • 另外,很棒的链接,我会仔细看看你的图书馆。
  • 如果您需要序列化操作,@Servy async void 很有用。 await OpenTheDoor(); await WalkThrough(); await CloseTheDoor();
  • @RaymondChen:一点也不。 async void 不提供超出async Task 所做的任何“序列化”,并且无法组合async void 方法(awaited)。
猜你喜欢
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2012-09-24
  • 2011-08-13
相关资源
最近更新 更多