2012-06-19 21 views
19

मुझे आश्चर्य है कि क्या लिंक एक्सटेंशन विधियां परमाणु हैं? या क्या मुझे किसी भी प्रकार के पुनरावृत्ति से पहले lock किसी भी IEnumerable ऑब्जेक्ट को धागे में इस्तेमाल किया जाना चाहिए?IENumerable लिंक विधियों थ्रेड-सुरक्षित हैं?

वैरिएबल को volatile के रूप में घोषित करते हुए इस पर कोई असर पड़ता है?

समेकित करने के लिए, निम्न में से कौन सा सबसे अच्छा, थ्रेड सुरक्षित, ऑपरेशन है?

किसी भी ताले बिना 1-:

IEnumerable<T> _objs = //... 
var foo = _objs.FirstOrDefault(t => // some condition 

2- ताला बयानों सहित:

IEnumerable<T> _objs = //... 
lock(_objs) 
{ 
    var foo = _objs.FirstOrDefault(t => // some condition 
} 

3- रूप में अस्थिर चर घोषणा:

volatile IEnumerable<T> _objs = //... 
var foo = _objs.FirstOrDefault(t => // some condition 
+0

वे धागे सुरक्षित नहीं हैं। Http://stackoverflow.com/questions/9995266/how-to-create-a-thread-safe-generic-list देखें – stuartd

उत्तर

20

इंटरफ़ेस IEnumerable<T> धागा सुरक्षित नहीं है। http://msdn.microsoft.com/en-us/library/s793z9y2.aspx पर प्रलेखन देखें, जो बताता है:

एक गणनाकर्ता तब तक मान्य रहता है जब संग्रह अपरिवर्तित रहता है। यदि संग्रह में परिवर्तन किए जाते हैं, जैसे तत्व जोड़ना, संशोधित करना या हटाना, तो गणनाकर्ता को अपरिवर्तनीय रूप से अमान्य कर दिया गया है और इसका व्यवहार अपरिभाषित है।

गणक के पास संग्रह तक विशेष पहुंच नहीं है; इसलिए, संग्रह के माध्यम से गणना करना आंतरिक रूप से थ्रेड-सुरक्षित प्रक्रिया नहीं है। गणना के दौरान थ्रेड सुरक्षा की गारंटी के लिए, आप संपूर्ण गणना के दौरान संग्रह को लॉक कर सकते हैं। संग्रह को पढ़ने और लिखने के लिए संग्रह को कई धागे से एक्सेस करने की अनुमति देने के लिए, आपको अपना सिंक्रनाइज़ेशन लागू करना होगा।

Linq इस बात का कोई परिवर्तन नहीं होगा।

लॉकिंग स्पष्ट रूप से वस्तुओं तक पहुंच को सिंक्रनाइज़ करने के लिए उपयोग किया जा सकता है। ऑब्जेक्ट को उस स्थान पर लॉक करना होगा जहां आप इसे एक्सेस करते हैं, न कि जब इसे फिर से चालू किया जाए।

संग्रह को अस्थिर के रूप में घोषित करने का कोई सकारात्मक प्रभाव नहीं होगा। यह केवल एक पढ़ने से पहले एक स्मृति बाधा में और संग्रह करने के लिए संदर्भ का एक लिखने के बाद परिणाम है। यह संग्रह पढ़ने या लिखने को सिंक्रनाइज़ नहीं करता है।

7

संक्षेप में, वे उपरोक्त वर्णित धागे सुरक्षित नहीं हैं।

हालांकि, इसका मतलब यह नहीं है कि आपको "हर तरह के पुनरावृत्ति" से पहले लॉक करना होगा।

आप अन्य कार्यों के साथ (जोड़ने, संशोधित करने या तत्वों निकालने के लिए) कि (जोड़ने, संशोधित करने तत्वों को हटाने, या तत्वों पढ़ें) सभी कार्यों कि संग्रह बदलने सिंक्रनाइज़ करने के लिए की जरूरत है।

आप केवल संग्रह पर पढ़ने के संचालन प्रदर्शन कर रहे हैं समवर्ती, कोई ताला की जरूरत है। (इसलिए औसत, कंटेनर, ElementAtOrDefault जैसे LINQ कमांड सभी एक साथ ठीक होंगे)

यदि संग्रह में तत्व मशीन शब्द की लंबाई के हैं, जैसे कि अधिकांश 32-बिट कंप्यूटरों पर Int, तो उस तत्व के मान को बदलना पहले से ही परमाणु प्रदर्शन किया गया है।इस मामले में लॉकिंग के बिना संग्रह से तत्वों को जोड़ या हटाएं, लेकिन मानों को संशोधित करना ठीक हो सकता है, अगर आप अपने डिज़ाइन में कुछ गैर-निर्धारणा से निपट सकते हैं।

आखिरकार, आप संपूर्ण संग्रह को लॉक करने के बजाय अलग-अलग तत्वों या संग्रह के अनुभागों पर बढ़िया लॉकिंग पर विचार कर सकते हैं।