2014-12-19 5 views
6

उदाहरण के लिए निम्नलिखित कोड धागा सुरक्षित है:समवर्ती संग्रह धागे सुरक्षित पर linq संचालन सुरक्षित हैं?

ConcurrentQueue<Guid> _queue = new ConcurrentQueue<Guid>(); 
     while(true) 
     { 
      for(int y = 0; y < 3; y++) 
      { 
       if(y % 3 == 0) 
       { 
        System.Threading.Tasks.Task.Run(() => _queue.Enqueue(Guid.NewGuid())); 
       } 
       else if (y % 3 == 1) 
       { 
        Guid x; 
        System.Threading.Tasks.Task.Run(() => _queue.TryDequeue(out x)); 
       } 
       else if(y % 3 == 2) 
       { 
        System.Threading.Tasks.Task.Run(() => 
        { 
         if (_queue.Any(t => t == testGuid)) 
         { 
          // Do something 
         } 
        }); 

       } 
      } 

संपादित करें: जाहिर है शीर्षक काफी स्पष्ट तो कोड नमूना अद्यतन वास्तविक बहु पिरोया व्यवहार शामिल करने के लिए नहीं था, हाँ कोड ऊपर सिर्फ एक नमूना है बहुप्रचारित व्यवहार का।

+3

धागा कहाँ है? – leppie

+0

आपके पास यह एएसपीनेट ऐप में हो सकता है और एकाधिक थ्रेड इसे मैन्युअल रूप से बनाये बिना इसे एक्सेस करेंगे – pollirrata

+1

आपके कोड में कोई बहु थ्रेडिंग नहीं है लेकिन यदि आप एक बहुप्रचारित वातावरण में हैं तो ConcurrentQueue निश्चित रूप से उपयोग करने के लिए एक अच्छा प्रकार है क्योंकि यह प्रदान करता है आपके कतार में सुरक्षित पहुंच। – FloChanz

उत्तर

8

LINQ संचालन केवल पढ़ने के लिए हैं, इसलिए वे सभी संग्रह पर थ्रेड सुरक्षित हैं। बेशक, यदि आप कोड जोड़ते हैं जो Where या Select विधि के अंदर संग्रह को संशोधित करता है, तो वे थ्रेड-सुरक्षित होने के लिए बंद हो जाते हैं।

थ्रेड-सुरक्षित संग्रह सुनिश्चित करते हैं कि संशोधनों थ्रेड-सुरक्षित हैं, जो LINQ क्वेरी निष्पादित करते समय वास्तव में कोई चिंता नहीं है।

सुरक्षित नहीं है ट्रैवर्सल के दौरान संग्रह को संशोधित करना। जब सामान्य रूप से संशोधित होते हैं तो सामान्य संग्रह इटरेटर्स को अमान्य करते हैं, जबकि थ्रेड-सुरक्षित संग्रह नहीं होते हैं। कुछ मामलों में, (उदाहरण के लिए ConcurrentQueue में) यह पुनरावृत्ति के दौरान डेटा का एक स्नैपशॉट पेश करके हासिल किया जाता है।

+0

धन्यवाद, यही वह था जो मैं बाद में था। इसलिए यदि मैं LINQ संचालन और संग्रह संशोधन को पारस्परिक रूप से अनन्य बनाना चाहता हूं तो मुझे अपना लॉकिंग संग्रह लागू करना होगा। – AncientSyntax

+0

यह निर्भर करता है। यह एक अवरुद्ध संग्रह में एक कतार लपेटने के लिए उपयोगी हो सकता है और एक गणना के रूप में dequeueing बेनकाब। इसके बाद आप उस पर linq संचालन कर सकते हैं लेकिन कतार खाली होने पर ही ब्लॉक करें। या वास्तव में बिल्कुल अवरुद्ध नहीं है लेकिन कुछ और करें और फिर बाद में वापस आएं और linq संचालन दोहराएं। यह लॉकिंग के बिना और पूर्ण थ्रेड-सुरक्षा के साथ, linq सामान को समेकित रूप से संशोधित और कर रहा होगा। –

+0

तो इसका मतलब है कि स्नैपशॉट में लंबे समय तक LINQ क्वेरी पर स्टेल डेटा शामिल होने से बचने के लिए एक लॉक की आवश्यकता है? आप अभी भी मल्टीथ्रेडिंग मुद्दों के लिए कमजोर हैं। –

2

हाँ, documentation

System.Collections.Concurrent नाम स्थान के अनुसार कई धागे की सुरक्षित संग्रह कक्षाएं कि System.Collections और सिस्टम में इसी प्रकार के स्थान पर इस्तेमाल किया जाना चाहिए प्रदान करता है। संग्रह। जेनेरिक नेमस्पेस जब भी कई थ्रेड संग्रह को समेकित रूप से एक्सेस करते हैं।

+1

[यह प्रलेखन] (http://msdn.microsoft.com/en-us/library/dd287144%28v=vs.110%29.aspx) अधिक उपयोगी होगा क्योंकि यह विशेष रूप से संग्रह पर विधि कॉल के बारे में बात करता है LINQ का उपयोग करेगा। – Rawling

3

हाँ, पर ...

के अपने उदाहरण लेते हैं:

if(_queue.Any(t => t == testGuid)) 
{ 
    // Do something 
} 

अब इस नहीं, कोई फर्क नहीं पड़ता अन्य थ्रेड क्या कर रहे हैं, एक अपवाद के साथ प्रलेखित मायनों में छोड़कर असफल हो जायेगी (जिसमें इस मामले का मतलब किसी भी अपवाद के साथ विफल है), _queue को किसी अमान्य स्थिति में डालें, या गलत जवाब दें।

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

अब क्या?

// Do something पर आपका कोड संभवतः तभी किया जाना चाहिए जब testGuid से मेल खाने वाली कतार में कोई तत्व हो। दुर्भाग्य से हम नहीं जानते कि यह सच है या नहीं, क्योंकि समय की हेराक्लिटन धारा चल रही है, और हम सभी जानते हैं कि वहां इस तरह का एक ग्रिड था।

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

लेकिन // Do something कतार में testGuid की उपस्थिति पर निर्भर करता है, और कतार को हटा दिया जा रहा है, तो संपूर्ण रूप से कोड-ब्लॉक थ्रेड-सुरक्षित नहीं है, हालांकि लिंक अभिव्यक्ति है।

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