如何在C ++/Cli中使用等待 [英] How to consume an awaitable in C++/Cli
问题描述
async
/await
在C#世界中广受欢迎.异步功能还倾向于在应用程序中迅速传播:需要等待,因此调用函数必须是异步的,因此也是需要等待的等待方式,等等.
async
/await
gained a lot of popularity in the C# world the past few years. Async functions also tend to spread rapidly within an application: Awaitables need to be awaited, therefore the calling function must be async and is therefore also an awaitable which needs to be awaited,... and so forth.
我正在C ++/Cli项目中使用C#库.该库公开了异步API. Visual C ++编译器不支持async
/await
.因此,我无法等待该库提供给我的任何API.
I'm using a C# library in a C++/Cli project. The library exposes async APIs. The Visual C++ compiler does not support async
/await
. Hence I have no way to await any of the APIs the library gives me.
我有以下选择:
- Call the async function and "letting it go": Not an option since I often need the return values to proceed.
- Calling
Wait()
or accessing theResult
property of theTask
/Task<T>
objects the async function returns: Causes the infamous dead-lock of the UI thread.
有什么办法可以使这项工作成功吗?如果需要的话,我不介意同步执行异步API.
Is there any way to make this work? I wouldn't mind executing the async APIs synchronously if I have to.
推荐答案
在我看来,您的问题更多是更大问题的征兆.我个人尽量避免将业务逻辑放在C ++-CLI模块中.具体来说,我尝试将ref class
功能限制在3个主要区域:
To me, it sounds like your problem is more of a symptom of a bigger issue. I personally try to avoid as much as I can putting business logic in a C++-CLI module. Specifically, I try to limit a ref class
functionality to 3 main areas:
- 将托管方法调用转换为本地方法调用(必要时包括转换参数).
- 将本机返回值转换为托管返回值.甚至可以将接收回调的异步函数转换为返回
Task
的方法. - 将本机事件(回调)转换为托管事件.
- Translating managed method calls to native method calls (that includes transforming parameters if necessary).
- Translating native return values to managed return values. This can even be translating an asynchronous function receiving a callback to a method returning
Task
. - Translating native events (callbacks) to managed events.
我可能是错的,但是在您的情况下,听起来您的C ++代码没有很好地解耦,您最终将其不同部分连接到了C ++-CLI模块中.
I Might be wrong, but in your situation it sounds like your C++ code is not well decoupled and you end up wiring different parts of it inside a C++-CLI module.
关于您的问题,我将使用Task.ContinueWith
系列方法而不是async / await
来执行异步延续.但是,如果希望在特定的SynchronizationContext
(例如UI线程)上调用延续,则必须特别注意提供正确的TaskScheduler
.
As for your question, I would use Task.ContinueWith
family of methods to perform the asynchronous continuation instead of async / await
. Yet, If you want the continuation to be invoked on a specific SynchronizationContext
(such as UI thread) then special care must be taken to supply the right TaskScheduler
.
这篇关于如何在C ++/Cli中使用等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!