समवर्ती बैग से सभी आइटम कैसे निकालें?


जवाबों:


37

यद्यपि यह संभावित दौड़ की स्थिति के कारण पूरी तरह से स्पष्ट नहीं हो सकता है, यह पर्याप्त है:

while (!myBag.IsEmpty) 
{
   myBag.TryTake(out T _);
}

23
यह निश्चित रूप से परमाणु नहीं है। इसलिए समवर्तीबाग I पर एक विस्तार विधि के रूप में नहीं जोड़ा जाना चाहिए, क्योंकि अन्य सभी तरीकों का उपयोग परमाणु अभिगम की धारणा के साथ किया जाता है।
अनुपम

इसके अलावा, TryTake खाली होने के अलावा अन्य कारणों से विफल नहीं हो सकता?
BrainSlugs83

21
यह बहुत खतरनाक है। यदि एक और प्रक्रिया लगातार वस्तुओं को जोड़ रही है तो यह व्यस्त रह सकता है।
इवोटॉप्स

4
@Adam Houldsworth + की टिप्पणी से उत्तर बेहतर है।
क्रिस मैरिसिक

1
यदि यह एक खतरनाक समाधान है, तो इसे अभी भी क्यों स्वीकार किया गया है?
बैरिस एकर्ट

65

अपडेट 10/03/2017: जैसा कि @Lou सही बताता है, असाइनमेंट परमाणु है। इस उदाहरण में, ConcurrentBagइच्छा का निर्माण परमाणु नहीं होगा, लेकिन उस संदर्भ को चर में रखना परमाणु होगा - इसलिए लॉक करना या इसके Interlocked.Exchangeआसपास सख्ती की आवश्यकता नहीं है।

कुछ और पढ़ने:

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

क्या एक संदर्भ असाइनमेंट थ्रेडसेफ़ है?


आप हमेशा बैग तक ही पहुंच बना सकते हैं और इसका एक नया उदाहरण बना सकते हैं। बैग में आइटम जीसी के लिए पात्र होंगे यदि उन पर कुछ और नहीं है:

lock (something)
{
    bag = new ConcurrentBag();
}

या जैसा कि लुकाज़ोइड बताते हैं:

var newBag = new ConcurrentBag();
Interlocked.Exchange<ConcurrentBag>(ref bag, newBag);

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

यदि आप जानते हैं कि इस समय और कुछ भी बैग तक नहीं पहुंचेगा, तो विंग-एंड-ए-प्रेयर इसे और लॉक न करें :-)


एक बेहतर समाधान नहीं होगा कि आप जिस बैग का उपभोग करते हैं, उसके बैग के संदर्भ की एक प्रति ले लें, फिर आप केवल bag = newअशुद्धता के साथ कर सकते हैं ?
क्रिस मैरिसिक

1
@ChrisMarisic हाँ, यदि आप डेटा साझा करने से बिल्कुल भी बच सकते हैं तो आप इन मुद्दों से मुक्त हैं। हालाँकि इस प्रश्न का बहुत संदर्भ नहीं था।
एडम हल्ड्सवर्थ

10
Interlocked.Exchangeएक लॉक से बेहतर हो सकता है
लुकाज़ोइड

5
Interlocked.Exchangeयदि एक्सचेंज के समय एक और धागा बैग में जोड़ा जाता है तो कैसे काम करता है ? के Addदौरान बंद हो जाता है Exchange?
ब्रैंडन

2
.NET में असेंबल्स परमाणु हैं, दोनों लॉक और Interlocked.Exchangeयहां बेमानी हैं (और थ्रेड सुरक्षा प्रदान नहीं करते हैं)।
लू

24

चयनित उत्तर एक तरह का है, ठीक है, एक वर्कअराउंड, इसलिए मैं अपना वर्कअराउंड जोड़ रहा हूं।

मेरा समाधान System.Collections.Concurrent नाम स्थान में सभी उपलब्ध संग्रहों को देखने के लिए था, जहां यह संग्रह से सभी तत्वों को साफ़ करने के लिए तुच्छ था।

ConcurrentStack वर्ग एक है साफ () विधि है जो संग्रह से सभी तत्वों को निकाल देता है। वास्तव में, यह नामस्थान (वर्तमान में) का एकमात्र संग्रह है जो करता है। हां, आपको Push(T element)इसके बजाय करना है Add(T element), लेकिन स्पष्ट रूप से यह उस समय के लायक है जो बचा है।


1
हालांकि उनके संग्रह के बीच कई अन्य महत्वपूर्ण अंतर हैं। उदाहरण के लिए, यदि आपको यह निर्धारित करने की आवश्यकता है कि किसी दिए गए आइटम के संग्रह में यह एक थैले के साथ तुच्छ और कुशल दोनों है, लेकिन स्टैक के साथ नहीं।
सर्वि

@ सरवाई: हाँ लेकिन फिर भी। नहीं, वास्तव में, मैंने प्रो / कांग्रेस सूची लिखना शुरू कर दिया था, लेकिन यह वास्तव में इस बात पर निर्भर करता है कि आपकी आवश्यकताएं क्या हैं। उदाहरण के लिए, समवर्ती संग्रह बहुआयामी पहुंच के लिए अच्छे हैं, लेकिन उनमें से कोई भी आपको संग्रह में अनुक्रमण करने की अनुमति नहीं देता है, कुछ ऐसा जो आपको उनका उपयोग करने से रोक सकता है। सवाल विशेष रूप से एक समवर्ती बैग को साफ़ करने के बारे में था (यही वजह है कि मैं इसके पार आया था), और थ्रेड सुरक्षा के साथ संग्रह की तुच्छ समाशोधन मेरी आवश्यकता थी। मेरा जवाब संग्रह स्विच करने के लिए था।

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

@ अगर आप किसी दिए गए आइटम को एक में समाहित करते हैं तो आप कुशलता से कैसे निर्धारित कर सकते हैं ConcurrentBag? मैं ऐसा करने के लिए कोई भी मूल संपत्ति या विधि नहीं देख सकता। Containsगणना नहीं करता। यह सामान्य IEnumerableएस के लिए एक विस्तार विधि है , और यह कुशल लेकिन कुछ भी है।
थियोडोर जूलियास

9

वर्कअराउंड की भावना में .. ConcurrentDictionary<T, bool>एक परमाणु स्पष्ट है, लेकिन अगर कुंजी मौजूद है, तो भी आपको जल्दी से जांच करने की अनुमति देता है। 'जल्दी' निश्चित रूप से एक सापेक्ष शब्द है, लेकिन आपके उपयोग के आधार पर यह एक बड़े स्टैक की गणना करने की तुलना में तेज़ हो सकता है।


अच्छा है! इसे ऐसे उदाहरणों के लिए चुना गया कंटेनर प्रकार माना जाना चाहिए। इसी तरह से समवर्ती।
लेटेंसी


-2
int cnt = _queue.Count;
for (; cnt > 0; cnt--)
{
     _queue.TryDequeue(out img);
}

यह एक अनंत लूप में नहीं आता है, और वर्तमान समय की सामग्री को साफ करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.