我正在使用第三方API,它看起来像是使用事件驱动架构编写的。我正在对API上的一个方法进行异步调用,但该方法的响应仅在事件处理程序中返回。因此,我必须订阅该事件,然后调用API的方法调用。
伪代码示例:
private string myValue;
public async Task<string> TestPost()
{
// Subscribe to event
api.OnSomeAPIFunctionResponse += EventHandler1;
await CallAPIFunction(...with some parameters...);
return myValue;
}
private void EventHandler1(sender, args)
{
// This is the value I want to return in the previous function
myValue = args.value;
}
在上面的代码示例中,当我运行应用程序时,myValue为null,因为事件处理程序代码在函数返回执行后启动。
如何在TestPost函数返回之前异步执行事件处理程序。
请建议我在这里可以做些什么。
答案 0 :(得分:2)
你到底想要做什么?您可以通过调用MYVALUE
来获取TestPost.Wait()
的正确值,但这是一个阻塞操作,并且从UI线程调用它可能会导致死锁。
如果您尝试将值设置为函数的结果,则await
结果可能更好
var myVar = await TestPost();
此link更多地解释了async/await
修改强>
在回复您的评论时,您可以使用TaskCompletionSource
来实现您的目标。这是未经测试的代码,但可能是这样的:
public Task<string> TestPost()
{
var tcs = new TaskCompletionSource<string>();
// Subscribe to event
api.OnSomeAPIFunctionResponse += ( (s, e) => tcs.SetResult(args.value));
CallAPIFunction(...with some parameters....);
return tcs.Task;
}
然后你以同样的方式得到结果:
var myVar = await TestPost();
TaskCompletionSource
允许您转换旧的异步API以使用基于任务的异步模式。这反过来允许您使用任务并行库提供的功能,并使用.NET 4.5 async
和await
中的新关键字。它导致更简单的代码。您可以阅读Parallel .NET Team的Stephen Toub在this article中了解TaskCompletionSource
的更多信息