等待多个回调

6
我正在使用一个可以进行异步调用的库,当返回响应时,将调用带有结果的回调函数。这是一种简单的模式,但我现在遇到了障碍。如何对多个异步方法进行多次调用并等待(无阻塞)它们?当我从所有服务中获得数据后,我想调用自己的回调方法,该方法将获得异步方法返回的两个或更多值。

在这里,应该遵循哪种正确的模式?顺便说一句,我不能更改使用TPL或其他东西的库...我必须与它生活在一起。

public static void GetDataAsync(Action<int, int> callback)
{
    Service.Instance.GetData(r1 =>
    {
        Debug.Assert(r1.Success);
    });

    Service.Instance.GetData2(r2 =>
    {
        Debug.Assert(r2.Success);
    });

    // How do I call the action "callback" without blocking when the two methods have finished to execute?
    // callback(r1.Data, r2.Data);
}
2个回答

7
你需要的是类似于CountdownEvent的东西。尝试使用以下代码(假设您在.NET 4.0上):
public static void GetDataAsync(Action<int, int> callback)
{
    // Two here because we are going to wait for 2 events- adjust accordingly
    var latch = new CountdownEvent(2);

    Object r1Data, r2Data;    

    Service.Instance.GetData(r1 =>
    {
        Debug.Assert(r1.Success);
        r1Data = r1.Data;
        latch.Signal();
    });

    Service.Instance.GetData2(r2 =>
    {
        Debug.Assert(r2.Success);
        r2Data = r2.Data;
        latch.Signal();
    });

    // How do I call the action "callback" without blocking when the two methods have finished to execute?
    // callback(r1.Data, r2.Data);

    ThreadPool.QueueUserWorkItem(() => {
        // This will execute on a threadpool thread, so the 
        // original caller is not blocked while the other async's run

        latch.Wait();
        callback(r1Data, r2Data);
        // Do whatever here- the async's have now completed.
    });
}

2

您可以使用Interlocked.Increment来处理每个异步调用。当其中一个完成时,调用Interlocked.Decrement并检查是否为零,如果为零,则调用自己的回调函数。您需要在回调委托之外存储r1和r2。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接