简体   繁体   English

等待多个回调

[英]Wait for multiple callbacks

I am using a library which does asynchronous calls and when the response is returned a callback method is called with the result. 我正在使用一个执行异步调用的库,当返回响应时,将调用带有结果的回调方法。 This is a simple pattern to follow but I am now hitting a obstacle. 这是一个简单的模式,但我现在遇到了障碍。 How do I do multiple calls to asynchronous methods and wait (without blocking) for them? 如何对异步方法进行多次调用并等待(不阻塞)它们? When I got the data from all the service, I'd like to call my own callback method which will get the two (or more) values returned by the async method. 当我从所有服务获得数据时,我想调用我自己的回调方法,该方法将获得异步方法返回的两个(或更多)值。

What's the correct pattern to follow here? 这里遵循的正确模式是什么? By the way, I cannot change the library to use TPL or something else... I have to live with it. 顺便说一句,我不能改变库使用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);
}

What you want is something like a CountdownEvent . 你想要的是像CountdownEvent Try this (assuming you are on .NET 4.0): 试试这个(假设您使用的是.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.
    });
}

You could use Interlocked.Increment for each async call you make. 您可以为每个异步调用使用Interlocked.Increment When one completes, call Interlocked.Decrement and check for zero, if zero, call your own callback. 完成后,调用Interlocked.Decrement并检查零,如果为零,则调用您自己的回调。 You'll need to store r1 and r2 outside the callback delegates. 您需要将r1和r2存储在回调代理之外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM