2013-03-14 11 views
29

accepted answer to question "Why does this Parallel.ForEach code freeze the program up?" एक WPF अनुप्रयोग में ConcurrentBag द्वारा सूची उपयोग को प्रतिस्थापित करने की सलाह देता है।ब्लॉकिंग कोलेक्शन का उपयोग कब करें और जब सूची <T> की बजाय ConcurrentBag?

मुझे यह समझना है कि BlockingCollection इसके बजाय इस मामले में उपयोग किया जा सकता है?

उत्तर

56

आप वास्तव में BlockingCollection का उपयोग कर सकते हैं, लेकिन ऐसा करने में बिल्कुल कोई बात नहीं है।

सबसे पहले, ध्यान दें कि BlockingCollection एक संग्रह के आस-पास एक रैपर है जो IProducerConsumerCollection<T> लागू करता है। किसी भी प्रकार की है कि है कि इंटरफ़ेस को लागू करता है अंतर्निहित भंडारण के रूप में इस्तेमाल किया जा सकता:

जब आप एक BlockingCollection<T> वस्तु बनाने के लिए, आप केवल नहीं घिरे क्षमता, लेकिन यह भी संग्रह के प्रकार के उपयोग करने के लिए निर्दिष्ट कर सकते हैं। उदाहरण के लिए, आप पहले पहले आउट (एफआईएफओ) व्यवहार, या ConcurrentStack<T> ऑब्जेक्ट को पहले के लिए पहले आउट (LIFO) व्यवहार में पहले ConcurrentQueue<T> ऑब्जेक्ट निर्दिष्ट कर सकते हैं। आप किसी भी संग्रह वर्ग का उपयोग कर सकते हैं जो IProducerConsumerCollection<T> इंटरफ़ेस लागू करता है। BlockingCollection<T> के लिए डिफ़ॉल्ट संग्रह प्रकार ConcurrentQueue<T> है।

इसमें ConcurrentBag<T> शामिल है, जिसका अर्थ है कि आपके पास अवरुद्ध समवर्ती बैग हो सकता है। तो सादे IProducerConsumerCollection<T> और अवरुद्ध संग्रह के बीच क्या अंतर है?

BlockingCollection<T> एक IProducerConsumerCollection<T> उदाहरण के लिए एक आवरण के रूप में प्रयोग किया जाता है, हटाने के लिए अनुमति देता है जब तक डेटा हटा दिया जाना चाहिए उपलब्ध है ब्लॉक करने के लिए संग्रह से प्रयास करता है: BlockingCollection दस्तावेज़ों (जोर मेरा) कहते हैं। इसी तरह, एक BlockingCollection<T>लिए बनाया जा सकता लागू एक ऊपरी बाध्य डेटा तत्वों की संख्या में अनुमति पर IProducerConsumerCollection<T> [...]

के बाद से जुड़ा हुआ सवाल में क्या करना कोई जरूरत नहीं है इन चीजों में से कोई भी, BlockingCollection का उपयोग करके कार्यक्षमता की एक परत जोड़ता है जो अप्रयुक्त हो जाता है।

+0

@ जॉन, धन्यवाद, इससे मुझे मूर्खता की स्थिति से तोड़ने में मदद मिली और मुझे वास्तव में ConcurrentDictionary की आवश्यकता होने पर ConcurrentBag और BlockingCollection का अध्ययन करने में बहुत समय लगा – Fulproof

1

हां, आप इसके लिए BlockingCollection का उपयोग कर सकते हैं। finishedProxies परिभाषित किया जाएगा के रूप में:

BlockingCollection<string> finishedProxies = new BlockingCollection<string>(); 

और एक आइटम जोड़ने के लिए, आप लिखते थे:

finishedProxies.Add(checkResult); 

और इसके पूर्ण होने पर, आप सामग्री से एक सूची बना सकते हैं।

+2

जिम Mischel, अपनी [.NET संदर्भ मार्गदर्शिका] (http://www.informit.com/guides/guide.aspx?g=dotnet) पढ़ना। काश मैं इसे पहले खोज सकता था, इसलिए मेरी व्यावहारिक जरूरतों के करीब – Fulproof

6
  • List<T> एक संग्रह एकल थ्रेड अनुप्रयोगों में उपयोग करने के लिए बनाया गया है।

  • ConcurrentBag<T>ConcurrentCollection<T> तैयार किया गया है बहु धागा वातावरण में संग्रह का उपयोग आसान बनाने के लिए की एक उप-प्रकार है।यदि आप ConcurrentCollection का उपयोग करते हैं तो आपको अन्य धागे द्वारा भ्रष्टाचार को रोकने के लिए अपने संग्रह को लॉक नहीं करना होगा। आप डाल सकते हैं या विशेष लॉकिंग कोड लिखने की आवश्यकता के बिना अपने संग्रह से डेटा ले सकते हैं।

  • BlockingCollection<T> की आवश्यकता से छुटकारा पाने के लिए डिज़ाइन किया गया है कि धागे के बीच साझा संग्रह में नया डेटा उपलब्ध है या नहीं। यदि आपके से साझा संग्रह में नया डेटा डाला गया है तो उपभोक्ता थ्रेड तत्काल जाग जाएगा। इसलिए आपको की जांच करने की आवश्यकता नहीं है यदि कुछ समय उपभोक्ता थ्रेड के लिए नया डेटा अंतराल आमतौर पर थोड़ी देर में अंतराल में उपलब्ध होता है।
संबंधित मुद्दे