【问题标题】:How to call an Async API in a synchronous fashion?如何以同步方式调用 Async API?
【发布时间】:2014-09-10 02:38:00
【问题描述】:

假设您有一个典型的异步设计模式 API,它具有

  1. 启动异步进程的 Start 方法
  2. 进程完成时调用的回调

如何使用 .NET 3.5 以同步方式调用此 API 而不会在调用期间阻塞消息泵?

【问题讨论】:

  • 当然,如果您想要同步阻止某些内容 - 您可以使用在回调中设置的 ManualResetEvent 轻松完成此操作(当然可以是 lambda/closure),您只需.Wait 为它。
  • 为什么要在同步模式中调用这个函数?同步调用的字面意思是“阻塞直到完成”,所以如果你没有阻塞运行消息泵的 UI 线程,你想阻塞什么?您能否更新您的问题以显示此功能的预期用途,这将使我们更好地了解您要完成的工作。
  • @scottchamberlain:假设在这个 API 中没有同步函数可以调用。
  • @CarstenKönig:waitOne() 将阻塞 UI 线程并停止消息泵
  • @Denis waitOne 或任何会阻塞线程你在 - 这就是同步 -选择正确的线程是您的责任

标签: c# .net vb.net multithreading


【解决方案1】:

如果您想等待结果(同步调用)但不想阻塞消息泵(假设您的意思是 UI 线程),则必须使用单独的线程来执行调用(并等待它)

使用异步和等待:

// current thread is the UI thread
// so create/use a Task to wait for the call
var task = Task.Factory.StartNew( () => { DoJobAsync().Wait()});

UI 线程创建一个任务 (T1) 并立即返回。 T1 在不同的线程上运行。该线程调用一个异步函数(它返回另一个任务 T2),以便等待异步 T1 调用 Wait on T2 的结果。

这太做作了:

  1. 异步方法的意图是异步执行,可能是因为它需要相当长的时间才能完成。
  2. 任务 T1 允许 UI 继续调用代码的下一行(与从注册延续的 UI 线程使用异步/等待相反。但现在您可能需要通过其他方式从 T1 获取结果。

【讨论】:

  • 我只有 .NET 3.5,所以没有异步/等待。你会如何在 .NET 3.5 中做到这一点?
  • @Denis - 在 .NET 3.5 中你很可能会使用回调模式
  • @denis - 这取决于您使用的 API。如果您自己创建线程,则可以使用 thread.join 来等待线程。或者,如果内部函数设置了一个等待句柄,你可以等待。如果内部函数接受回调,则在回调中设置等待句柄并等待
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 2014-05-01
  • 2019-05-26
  • 1970-01-01
  • 2017-04-14
相关资源
最近更新 更多