2011-01-05 15 views
6

के साथ मल्टी-थ्रेडिंग मूल थ्रेड (Multi-threading with Linq to SQL) अब तक काफी पुराना हो गया है, मैंने सोचा है कि मैं एक और विषय पर एक और प्रश्न पोस्ट करूंगा। एक परिदृश्य पर विचार करें, जहां एक डोमेन सेवा SQL सर्वर डेटाबेस से डेटा पुनर्प्राप्त करने के लिए कई विधियों का खुलासा करती है। जाहिर है, एक बहु उपयोगकर्ता परिदृश्य में, एक साथ कई अनुरोध आने के साथ, किसी को इसकी उम्मीद करनी होगी। डेटा कॉन्टेक्स्ट को समानांतर में उपयोग किया जाना चाहिए, बिना किसी नियंत्रण के और डेवलपर से उन एकाधिक अनुरोधों को संभालने के लिए अतिरिक्त प्रयास। तो कैसे आते हैं, अगर मैं अपने अनुक्रमिक LINQ प्रश्नों को समानांतर में डालता हूं। इन्वोक(), सभी नरक टूट जाते हैं और मुझे डर लगता है "पहले से ही एक बंद डेटा रीडर इस कमांड से जुड़ा हुआ है जिसे पहले बंद किया जाना चाहिए।" त्रुटि ...?लिंक से एसक्यूएल

प्रदर्शित करने के लिए, इस काम करता है:

List<Data> retVal = new List<Data>(); 

retVal.AddRange(this.DataContext.Table1.Where(w=>w.A==1).Select(s=>new Data{f1=s.D}).ToList()); 
retVal.AddRange(this.DataContext.Table1.Where(w=>w.B==2).Select(s=>new Data{f1=s.D}).ToList()); 
retVal.AddRange(this.DataContext.Table1.Where(w=>w.C==3).Select(s=>new Data{f1=s.D}).ToList()); 

... और अभी तक यह नहीं करता है:

List<Data> retVal = new List<Data>(); 
Parallel.Invoke(
()=>retVal.AddRange(this.DataContext.Table1.Where(w=>w.A==1).Select(s=>new Data{f1=s.D}).ToList()), 
()=>retVal.AddRange(this.DataContext.Table1.Where(w=>w.B==2).Select(s=>new Data{f1=s.D}).ToList()), 
()=>retVal.AddRange(this.DataContext.Table1.Where(w=>w.C==3).Select(s=>new Data{f1=s.D})).ToList()); 

एक दूसरे कि सूची के लिए कोई बात नहीं है नहीं थ्रेड-सुरक्षित, त्रुटि के रूप में एसक्यूएल डेटा कनेक्शन से आ रहा है।

कोई अंतर्दृष्टि और स्पष्टीकरण की सराहना की जाएगी।

उत्तर

10

पहला, स्पष्टीकरण के लिए, यह मुद्दा बहु-उपयोगकर्ताओं के बजाय बहु-थ्रेडिंग के साथ करना है। एक बहु-उपयोगकर्ता परिदृश्य में, प्रत्येक उपयोगकर्ता के पास DataContext उदाहरण होगा, साझा उदाहरणों के आसपास थ्रेडिंग समस्याओं से परहेज करें।

समांतर उदाहरण विफल रहता है क्योंकि DataContext थ्रेड-सुरक्षित ऑब्जेक्ट नहीं है; यह एक धागे द्वारा उपयोग किया जाने की अपेक्षा करता है, न कि समानांतर में कई लोगों द्वारा। यह डेटा पाठकों से जुड़े अपवाद के रूप में उभरता है, क्योंकि DataContext का कनेक्शन खुला होता है, जब आप समानांतर में दूसरे कथन को निष्पादित करने का प्रयास करते हैं तो डेटा रीडर के साथ पढ़ना।

यदि आप किसी भी धारावाहिक तकनीकों के बिना कई धागे में SqlConnection उदाहरण का उपयोग करने का प्रयास करते हैं तो वही समस्या स्पष्ट होगी।

+0

अच्छी तरह से डालें, बहु-उपयोगकर्ता = 'डेटाकॉन्टेक्स्ट' ** प्रति ** धागा। – Nate

+0

धन्यवाद, हीरो, यह बहुत मदद करता है। – Darek

+0

@Nate: मैं आगे जाऊंगा। यह काम की प्रति यूनिट 'डेटाकॉन्टेक्स्ट' होना चाहिए, जो भी आप काम की इकाई तय करते हैं, वह होता है। – jason

8

आपको धागे में DataContext साझा नहीं करना चाहिए। यह स्वाभाविक रूप से असुरक्षित है। इसके अतिरिक्त, DataContext एस का उपयोग प्रति इकाई एक इकाई (यानी, प्रति बातचीत एक) के लिए किया जाता है। प्रत्येक अनुरोध को एक अलग बातचीत माना जाना चाहिए और एक अद्वितीय DataContext के साथ उत्तर दिया जाना चाहिए।

+0

अच्छा जवाब भी। – Darek

+0

यह असुरक्षित क्यों है? – paIncrease

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