【问题标题】:Async Event Subscription异步事件订阅
【发布时间】:2014-03-20 10:50:53
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

    你到底想做什么?您可以通过调用TestPost.Wait() 来获得MYVALUE 的正确值,但这是一个阻塞操作,从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 团队的 Stephen Toub 的 this article 中阅读有关 TaskCompletionSource 的更多信息

    【讨论】:

    • 谢谢,但请阅读我所说的帖子,我订阅的事件返回结果,而不是等待它的实际函数。我想同时运行事件和事件处理程序,因此当 TestPost 函数返回时,它具有来自事件处理程序参数的值。谢谢:)
    猜你喜欢
    • 2020-09-11
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多