异步事件订阅

时间:2014-03-19 10:10:49

标签: c# asp.net-mvc async-await event-driven

我正在使用第三方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函数返回之前异步执行事件处理程序。

请建议我在这里可以做些什么。

1 个答案:

答案 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 asyncawait中的新关键字。它导致更简单的代码。您可以阅读Parallel .NET Team的Stephen Toub在this article中了解TaskCompletionSource的更多信息