2012-05-31 22 views
6

मैं एक लाइब्रेरी का उपयोग कर रहा हूं जो एसिंक्रोनस कॉल करता है और जब प्रतिक्रिया वापस आती है तो कॉलबैक विधि परिणाम के साथ बुलाया जाता है। यह पालन करने के लिए एक सरल पैटर्न है लेकिन अब मैं बाधा मार रहा हूं। मैं एसिंक्रोनस विधियों के लिए एकाधिक कॉल कैसे करूं और उनके लिए प्रतीक्षा कर रहा हूं (अवरुद्ध किए बिना)? जब मुझे सभी सेवाओं से डेटा मिला, तो मैं अपनी कॉलबैक विधि को कॉल करना चाहता हूं जो एसिंक विधि द्वारा दो (या अधिक) मान लौटाएगा।एकाधिक कॉलबैक के लिए प्रतीक्षा करें

यहां पालन करने के लिए सही पैटर्न क्या है? वैसे, मैं पुस्तकालय को टीपीएल या कुछ और उपयोग करने के लिए नहीं बदल सकता ... मुझे इसके साथ रहना है।

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 async आप कर कहते हैं। जब कोई पूरा हो जाता है, तो Interlocked.Decrement पर कॉल करें और शून्य के लिए जांचें, शून्य होने पर, अपना कॉलबैक कॉल करें। आपको कॉलबैक प्रतिनिधियों के बाहर आर 1 और आर 2 स्टोर करने की आवश्यकता होगी।

संबंधित मुद्दे