如何在 C++/Cli 中使用 awaitable

kol*_*man 5 .net c# c++-cli async-await

async/await在过去几年中在 C# 世界中获得了很大的人气。异步函数也倾向于在应用程序中快速传播:Awaitables 需要等待,因此调用函数必须是异步的,因此也是一个需要等待的 awaitable,等等。

我在 C++/Cli 项目中使用 C# 库。该库公开异步 API。Visual C++ 编译器不支持async/ await。因此,我无法等待库提供给我的任何 API。

我有以下选择:

  • 调用异步函数并“放手”:不是一个选项,因为我经常需要返回值才能继续。
  • 调用Wait()或访问异步函数返回ResultTask/Task<T>对象的属性:导致UI 线程臭名昭著的死锁

有什么办法可以使这项工作?如果必须的话,我不介意同步执行异步 API。

Ela*_*oni 1

对我来说,听起来你的问题更像是一个更大问题的症状。我个人尽量避免将业务逻辑放入 C++-CLI 模块中。具体来说,我尝试将ref class功能限制在 3 个主要区域:

  • 将托管方法调用转换为本机方法调用(包括必要时转换参数)。
  • 将本机返回值转换为托管返回值。这甚至可以将接收回调的异步函数转换为返回的方法Task
  • 将本机事件(回调)转换为托管事件。

我可能是错的,但在你的情况下,听起来你的 C++ 代码没有很好地解耦,你最终将它的不同部分连接到 C++-CLI 模块中。

至于你的问题,我会使用Task.ContinueWith一系列方法来执行异步延续而不是async / await. 然而,如果您希望在特定(例如 UI 线程)上调用延续SynchronizationContext,则必须特别注意提供正确的TaskScheduler.