C++
和 Windows Universal App中的C#
之间的通信。我们知道下面是从C++
调用C#
函数的方法。class FooCS
{
FooCS()
{
FooC c = new ref FooC();
c.m_GetSomeValueEvent = GetSomeValueEvent;
// Some other stuff ...
}
string GetSomeValueEvent()
{
// Some other stuff ...
return "Hello World";
}
}
C++
public delegate Platform::String GetSomeValueEventHandler();
class FooC
{
public:
event GetSomeValueEventHandler^ m_GetSomeValueEvent;
void someFunction(){
Platform::String^ str = m_GetSomeValueEvent();
// Some other stuff ...
}
}
以上内容非常简单明了。但问题在于,在 C#
中,该字符串 GetSomeValueEvent()
执行一些繁重的任务,例如从数据库中读取数据,因此我必须将其改为 async
。
async Task<string> GetSomeValueEvent() {
// Some other stuff ...
return "Hello World";
}
现在问题来了:我该如何让我的C++
代码等待这个委托函数的返回呢?换句话说,下面的签名应该如何修改?
public delegate Platform::String GetSomeValueEventHandler();
我已经在Google上搜索了很久,但是找不到这个问题的正确术语。如果您确定它是不可能的,至少知道也是好的。
最终,这就是我们要做的:
string GetSomeValueEvent() {
// Convert a async method to non-async one
var val = someAsyncMethod().Result;
// Some other stuff ...
return "Hello World";
}
为了防止死锁,必须确保GetSomeValueEvent
不在主线程上运行。
GetDeferral
方法和一些报告结果机制的EventArgs
参数。每个委托都需要一个延迟,执行其异步工作,通过报告机制(可能是SetResult
方法或将结果附加到集合中)报告结果,然后完成延迟。当最后一个延迟完成时,调用者检查所有报告的结果。 - Raymond Chendeferral
模式而不是async delegate
并不是一个好主意,正如Raymond所建议的那样。我最终通过使用Result
从C#中删除了async
。如果您有兴趣,请随时查看我的修改后的问题(在底部)。 - Yuchen