Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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);
}
like image 665
Martin Avatar asked May 31 '12 01:05

Martin


1 Answers

What you want is something like a CountdownEvent. Try this (assuming you are on .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.
    });
}
like image 58
Chris Shain Avatar answered Sep 30 '22 19:09

Chris Shain