2010-10-28 11 views
15

क्या मैं लॉकिंग के बिना, सुरक्षित रूप से सूची को कॉल कर सकता हूं। एकाधिक धागे से एड्रेंज (आर)? यदि नहीं, तो मैं किस तरह की परेशानी में भागूँगा?सूची <T> है .ddRange() धागा सुरक्षित है?

+1

बीटीडब्ल्यू - फिर 'किस तरह की परेशानी?' - आपको कुछ यादृच्छिक समय पर एक अपवाद मिल जाएगा, जब एकाधिक धागे –

उत्तर

17

नहीं, its documentation यह नहीं कहता कि यह थ्रेड सुरक्षित है, इसलिए यह नहीं है।

सार्वजनिक स्थैतिक (विजुअल बेसिक में साझा) इस प्रकार के सदस्य थ्रेड सुरक्षित हैं। कोई भी इंस्टेंस सदस्य नहीं है जो थ्रेड सुरक्षित होने की गारंटी देता है।

क्या गलत हो सकता है के रूप में, क्या AddRange (newItems) के बारे में सोचना है: आंतरिक सरणी में पर्याप्त जगह

  • है

    • जांच करें कि यदि नहीं:
      • का आवंटन एक नया सरणी
      • वर्तमान आइटम को नई सरणी
      • पर कॉपी करें नए एआर पर इंगित करने के लिए फ़ील्ड सेट करें ay
    • कॉपी आंतरिक सरणी
    • अद्यतन में सही स्थानीय करने के लिए newItems क्षेत्र "गिनती" (यह जहां अगले आइटम डाला जाता है को नियंत्रित करने के लिए किया जाता है)

    अब लगता है कि क्या होगा तब होता है जब उपरोक्त को AddRange() या किसी आइटम को पढ़ने के लिए केवल एक कॉल के साथ मिश्रित किया जाता है।

  • 1

    नहीं, यह थ्रेड-सुरक्षित नहीं है।

    थ्रेड ए आपकी सूची में AddRange को कॉल कर सकता है। यह संग्रह और आंशिक स्विच पर आंशिक रूप से पुन: सक्रिय हो सकता है।

    थ्रेड बी थ्रेड ए समाप्त होने से पहले जोड़ें/निकालें आदि कॉल कर सकता है।

    6

    नहीं, यह नहीं है, लेकिन मैं myList.AddRange(...); को lock (syncLock) { myList.Add(...) }; करने की तुलना में लॉक के भीतर इसे और अधिक कुशल बनाना चाहता हूं।

    आप किस तरह की परेशानी में भाग लेंगे? जब एक धागा एक आइटम जोड़ रहा है, जबकि कोई अन्य सूची की गणना कर रहा है, List<T> एक निश्चित अपवाद फेंक देगा क्योंकि यह कुछ आंतरिक संस्करण करता है, क्योंकि यह हमें खराब डेवलपर्स को खराब दुष्प्रभावों से टकराने से रोकना चाहता है।

    इसके अलावा List<T> आंतरिक रूप से एक सरणी रखता है जिसमें यह अपनी वस्तुओं को संग्रहीत करता है। हो सकता है कि किसी सरणी में कोई आइटम सेट करना बहुत परमाणु है, लेकिन जब भी इस सरणी की क्षमता तक पहुंच जाती है, तो एक नया बनाया जाएगा और आइटम को पुराने से कॉपी किया जाएगा। तो जब एक प्रतिलिपि उस प्रतिलिपि के दौरान कुछ जोड़ना चाहती है, तो आप कल्पना कर सकते हैं कि चीजें सिंक से बाहर हो जाएंगी।

    +0

    उत्कृष्ट उत्तर, धन्यवाद। =) –

    3

    .NET Framework 4.0 तक, कोई .NET संग्रह थ्रेड-सुरक्षित नहीं है। इसके बाद आपको अपने कोड Collections and Synchronization (Thread Safety) में इसे एक्सेस करने से पहले इसे लॉक करना होगा।

    दूसरी ओर, .NET Framework 4।0 नए System.Collections.Concurrent नामस्थान पेश करता है जिसमें ठीक-ठीक Thread-Safe Collections शामिल है।

    अंत में, यदि आप .NET Framework 4.0 का उपयोग कर सकते हैं, तो मैं दृढ़ता से अनुशंसा करता हूं कि आप जो भी चाहते हैं उसके लिए ऐसा करें, अन्यथा, जब भी आप इसे संशोधित करना या एक्सेस करना चाहते हैं तो संग्रह को लॉक करना सुनिश्चित करें।

    इसके अलावा, एक स्थिर संग्रह थ्रेड-सुरक्षित होना चाहिए, लेकिन सावधान रहें, क्योंकि सदस्यों की गारंटी नहीं है।

    संपादित करें # 1

    स्टीव टाउनसेंड की टिप्पणी की वजह से आगे सत्यापन के बाद, मैं मानता .नेट फ्रेमवर्क के भीतर तीन धागे की सुरक्षित संग्रह संस्करण 3.0 के साथ शुरू देखते हैं कि:

    1. SynchronizedCollection Generic Class;
    2. SynchronizedKeyedCollection Generic Class;
    3. SynchronizedReadOnlyCollection Generic Class

    मैं क्षमा चाहता हूं, मैंने अभी अपना एक्जिन्सेंस सीखा है। =)

    +0

    सत्य नहीं है, कुछ 'System.Collections.Generic' में हैं जो यहां काम करते हैं और 4.0 –

    +0

    @ स्टेव टाउनसेंड का अनुमान लगाते हैं: सत्यापन के बाद, आप सही हैं, मैं गलत हूं। इसके अलावा, 'IList ' सामान्य संग्रह नहीं है, हालांकि मैंने इसे 'सिंक्रनाइज़ किया गया चयन ' नहीं माना था, क्योंकि मुझे इसके बारे में पता नहीं था। = पी मुझे सूचित करने के लिए धन्यवाद! –

    +1

    कोई समस्या नहीं है। मैं 4.0 संग्रह का उल्लेख करने के लिए आपको एक +1 देना चाहता हूं। –

    3

    आपके उपयोग के आधार पर, SynchronizedCollection काम कर सकता है।

    आपके पास कोई एकल शॉट AddRange नहीं होगा। यदि आप केवल संग्रह के बीज के लिए इसका उपयोग कर रहे हैं, तो आप ऐसा कर सकते हैं क्योंकि IEnumerable कन्स्ट्रक्टर अधिभार है।

    +1

    +1 मैंने अभी कुछ नया सीखा है! धन्यवाद! =) –

    +0

    आपके अपवोट के लिए धन्यवाद। मैं आपको यह बताना चाहता हूं कि मैंने आपके द्वारा प्रदान की गई इस नई जानकारी को दर्शाने के लिए मेरा जवाब संपादित किया है (हम सभी)। –

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