2012-05-31 100 views
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); 
} 

回答

6

你想要的東西就像是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。