2012-07-09 20 views
7

का उपयोग करने का एक बेहतर तरीका क्या होगा मैंने अभी टीपीएल का उपयोग शुरू किया है, और मैं समानांतर में वेब सेवाओं पर कई कॉल करना चाहता हूं। जो मैं इकट्ठा कर सकता हूं, उससे मैं इसे करने के दो तरीके देखता हूं।कार्य समानांतर लाइब्रेरी

या तो Parallel.ForEach:

List<ServiceMemberBase> list = new List<ServiceMemberBase>(); //Take list from somewhere. 
     Parallel.ForEach(list, member => 
      { 
       var result = Proxy.Invoke(member); 
       //... 
       //Do stuff with the result 
       //... 
      }); 

या Task<T>: अगर वाक्य रचना सही है या नहीं

List<ServiceMemberBase> list = new List<ServiceMemberBase>(); //Take list from somewhere. 
     ForEach(var member in list) 
     { 
      Task<MemberResult>.Factory.StartNew(() => proxy.Invoke(member)); 
     } 

     //Wait for all tasks to finish. 
     //Process the result objects. 

की अनदेखी, कर रहे हैं इन बराबर करने के लिए?

क्या वे एक ही परिणाम उत्पन्न करेंगे? यदि नहीं, क्यों? और कौन सा बेहतर है?

उत्तर

5

कोड और उपयोग के मामले के लिए आप चर्चा करते हैं, दोनों दृष्टिकोण अनिवार्य रूप से समकक्ष हैं।

समानांतर। फोरएच उपयोगी है जब आपको कई कार्यों (यहां लागू नहीं) पर इनपुट रेंज को विभाजित करना होता है, या कई स्वतंत्र समांतर संचालन के परिणाम विलय को सिंक्रनाइज़ करना आसान होता है (शायद यहां लागू होता है?)।

किसी भी मामले में, आपने सही तरीके से ध्यान दिया है कि समांतर में। किसी भी मामले में, आपको मैन्युअल रूप से पूरा होने के इंतजार को सिंक्रनाइज़ करने की आवश्यकता नहीं है, जबकि यदि आप मैन्युअल रूप से कार्य शुरू करते हैं, तो आपको स्वयं सिंक्रनाइज़ेशन का प्रबंधन करना होगा। इस मामले में आप शायद Task.WaitAll(...) जैसे कुछ का उपयोग करेंगे।

+0

उत्तर के लिए धन्यवाद। मैं समांतर का उपयोग कर समाप्त हुआ। फॉरएच और हम अपने उत्पादन पर प्रतिक्रिया समय में लगभग 25% के सुधार को देखते हैं - 16 कोर मशीनें।मैं अनुमान लगा रहा हूं कि अधिकांश लाभ समांतर डेटा प्रोसेसिंग में है, न कि वेब सेवाओं के समानांतर कॉल में। –

1

आउटपुट को प्रतिबिंबित या देखे बिना मैं कुछ निश्चित नहीं कह सकता कि दोनों एक जैसे हैं या नहीं; हालांकि मुझे संदेह होगा कि क्या वे बहुत अलग हैं। परिदृश्य के आधार पर सवाल बेहतर है। उत्तर देने के लिए जो बेहतर है, वह फिर से बहुत ही व्यक्तिपरक है, आपके द्वारा प्रदान किए गए परिदृश्य में मैं कहूंगा कि मैं समानांतर पसंद करूंगा। फॉरएच क्योंकि मैं इसे पढ़ सकता हूं लेकिन यदि आपकी विकास टीम समानांतर लाइब्रेरी में उपयोग नहीं की जाती है तो दूसरा संस्करण है एक के लिए जाने के लिए।

1

कोड के दो टुकड़ों के बीच, Parallel.ForEach() अधिक कुशल होगा, क्योंकि यह एक से अधिक Task में एक से अधिक वस्तुओं को संसाधित करता है, एक के बाद।

लेकिन उनमें से दोनों ThreadPool के रूप में कई धागे का उपयोग करेंगे, जो इस मामले में एक अच्छा विचार नहीं है। ऐसा इसलिए है क्योंकि ThreadPool थ्रेड की इष्टतम संख्या अनुमान लगाने में अच्छा है यदि आपके पास बहुत छोटा, सीपीयू-बाउंड Task एस है, जो यहां से बहुत दूर है।

इस कारण से

, मुझे लगता है कि सबसे अच्छा विकल्प मैन्युअल रूप से एक छोटी संख्या को समानांतरवाद की डिग्री सीमित करना है (आप क्या संख्या सबसे अच्छा परिणाम देता है पता लगाने के लिए उपाय करने के लिए होगा):

List<ServiceMemberBase> list = …; //Take list from somewhere. 
Parallel.ForEach(list, new ParallelOptions { MaxDegreeOfParallelism = 10 }, 
member => 
{ 
    var result = Proxy.Invoke(member); 
    //... 
    //Do stuff with the result 
    //... 
}); 

भी अधिक कुशल होगा यदि आप वेब सेवा कॉल को असीमित रूप से निष्पादित कर सकते हैं। ऐसा करना और समानांतरता की डिग्री को एक ही समय में सीमित करना बहुत आसान नहीं है, जब तक कि आप सी # 5 पर न हों। यदि आप सी # 5 पर थे और यदि आपने टास्क-आधारित असिंक्रोनस पैटर्न (टीएपी) का समर्थन करने के लिए Proxy को भी अपडेट किया है, तो आप आपके कोड को और अधिक कुशलता से निष्पादित करने के लिए टीपीएल डेटाफ्लो का उपयोग कर सकते हैं:

var actionBlock = new ActionBlock<ServiceMemberBase>(
    async member => 
    { 
     var result = await Proxy.InvokeAsync(member); 
     //... 
     //Do stuff with the result 
     //... 
    } 
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 }); 
संबंधित मुद्दे