Așteptați mai multe apeluri de apel

Folosesc o bibliotecă care efectuează apeluri asincrone, iar atunci când răspunsul este returnat este apelată o metodă de apel invers cu rezultatul. Acesta este un model simplu de urmat, dar acum lovesc un obstacol. Cum fac mai multe apeluri la metode asincrone și aștept (fără a le blocheza) pentru ele? Când am primit datele din întregul serviciu, aș dori să-mi sun metodă de apel inversă care va primi cele două (sau mai multe) valori returnate de metoda async.

Care este modelul corect de urmat aici? Apropo, nu pot schimba biblioteca să folosească TPL sau altceva ... trebuie să trăiesc cu ea.

public static void GetDataAsync(Action 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);
}
6

2 răspunsuri

Ceea ce doriți este ceva asemănător cu CountdownEvent . Încercați acest lucru (presupunând că sunteți pe .NET 4.0):

public static void GetDataAsync(Action 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.
    });
}
6
adăugat

Ați putea folosi Interlocked.Increment pentru fiecare apel asincron pe care îl efectuați. Când se termină, apelați Interlocked.Decrement și verificați pentru zero, dacă zero, apelați propriul callback. Va trebui să stocați r1 și r2 în afara delegațiilor de apel invers.

2
adăugat