2010-11-12 11 views
6

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

अब, मुझे एहसास है कि मैं इसके लिए कई धागे का उपयोग कर सकता हूं - और यह सबसे आसान समाधान हो सकता है - लेकिन मैंने सोचा कि मैं एसिंक को आज़मा दूंगा।

मेरे कोड इस के समान है:

public delegate void Callback(string response); 

public static void InvokeAsync(string request, string url, Callback callback) 
    where TResponse: class 
{ 
    var web = new WebClient(); 
    web.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); 

    web.UploadStringCompleted += (sender, e) => callback.Invoke(e.Result); 
    web.UploadStringAsync(new Uri(url), request); 
} 

//... 
var lockObj = new object(); 
foreach (var item in list) 
    InvokeAsync(item, url, response => { lock(lockObj) newList.Add(response); }); 

ऊपर काम करना चाहिए, मेरा मानना ​​है कि; हालांकि, मेरी समस्या यह है कि मुझे नहीं पता कि सभी प्रतिक्रियाएं वापस आने तक प्रतीक्षा कैसे करें। यदि मैं काउंटर का उपयोग करता हूं और शून्य होने तक लूप में प्रतीक्षा करता हूं, तो कॉलबैक को संभालने के लिए कोई भी CPU शेष नहीं होगा। सैमफोर के कुछ रूपों का उपयोग करने के साथ ही, मुझे विश्वास है। क्या मैं इंतजार करने के लिए एक गैर-अवरुद्ध तरीका है जब तक कि मैं सभी प्रतिक्रियाओं को वापस नहीं मिला? (विधि हस्ताक्षर परिवर्तित करने से एक कॉलबैक लेने के लिए केवल एक समस्या यह एक स्तर ऊपर चले जाएँगे, मुझे डर लग रहा।)

[संपादित करें] यहाँ एक बहुत करीबी सवाल है - How to invoke async operation as sync? - लेकिन मैं कई async पर प्रतीक्षा करने की आवश्यकता संचालन।

उत्तर

3

इसके लिए आप AutoResetEvent का उपयोग करते हैं।

अपने अंतिम दो पंक्तियों के लिए निम्नलिखित का प्रयास करें:

var waitEvent = new AutoResetEvent(false); 

foreach (var item in list) 
    InvokeAsync(item, url, response => { lock(lockObj) newList.Add(response); waitEvent.Set(); }); 

while (newList.Count < list.Count) 
    waitEvent.WaitOne(); 

सभी आइटम पूरा किया जाना चाहिए जब newListlist के रूप में कई आइटम शामिल हैं। जब कोई नई वस्तु आती है, तो आप इसे newList पर जोड़ते हैं। फिर, आप waitEvent को संकेत देते हैं कि "कुछ" newList पर हुआ।

मुख्य धागे में, आप बस newList में पर्याप्त आइटम होने तक प्रतीक्षा करें और आप newList में परिवर्तनों की प्रतीक्षा करके इसके लिए प्रतीक्षा करें, जो waitEvent आपको सूचित करता है।

+0

धन्यवाद! मुझे इस साइट से प्यार है। –

+0

आपका स्वागत है। –

0

HTTP प्रोटोकॉल के अनुसार, कोई ग्राहक केवल सेवा के लिए 2 कनेक्शन खोल सकता है।

+0

http://blogs.msdn.com/b/wenlong/archive/2009/02/08/why-only-two-concurrent-requests-for-load-testing.aspx आपके साथ सहमत है, लेकिन ठीक करने का एक तरीका इंगित करता है उस; यदि मैंने उस सीमा को मारा तो मैं सुझाए गए समाधान का उपयोग करने की योजना बना रहा हूं। –

+0

HTTP प्रोटोकॉल के कनेक्शन पर कोई समग्र सीमा नहीं है, लेकिन अच्छे कारणों के लिए एक कनेक्शन के रूप में 2 कनेक्शन (या प्रॉक्सी या गेटवे कोड के लिए ग्राहकों की संख्या 2 गुना) है; ऐसा लगता है कि कई मामलों में, 2 प्रति सर्वर एक समय में खोलने के लिए सबसे कुशल संख्या है। .NET इसे लागू करता है, लेकिन यह विन्यास योग्य है। –

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