2010-04-04 16 views
7

मुझे पता चला कि एंटीटी फ्रेमवर्क में आलसी लोडिंग केवल उस थ्रेड से काम करती है जिसने ObjectContext बनाया है। समस्या को समझाने के लिए, मैंने एक साधारण परीक्षण किया, जिसमें एक साधारण मॉडल है जिसमें केवल 2 इकाइयां हैं: Person और AddressAddress संपत्ति lazily भरी हुई हैइकाई फ्रेमवर्क आलसी लोडिंग अन्य धागे से काम नहीं करती

private static void TestSingleThread() 
    { 
     using (var context = new TestDBContext()) 
     { 
      foreach (var p in context.Person) 
      { 
       Console.WriteLine("{0} lives in {1}.", p.Name, p.Address.City); 
      } 
     } 
    } 

    private static void TestMultiThread() 
    { 
     using (var context = new TestDBContext()) 
     { 
      foreach (var p in context.Person) 
      { 
       Person p2 = p; // to avoid capturing the loop variable 
       ThreadPool.QueueUserWorkItem(
        arg => 
        { 
         Console.WriteLine("{0} lives in {1}.", p2.Name, p2.Address.City); 
        }); 
      } 
     } 
    } 

TestSingleThread विधि ठीक काम करता है, यहाँ कोड है। लेकिन TestMultiThread में, मुझे p2.Address.City पर NullReferenceException मिलता है, क्योंकि p2.Address शून्य है।

यह एक बग है? क्या यह काम करने वाला तरीका है? यदि हां, तो क्या कोई दस्तावेज इसका उल्लेख कर रहा है? मुझे एमएसडीएन या Google पर इस विषय पर कुछ भी नहीं मिला ...

और सबसे महत्वपूर्ण बात यह है कि क्या कोई कामकाज है?

किसी भी मदद की बहुत सराहना की जाएगी जा

पी एस (स्पष्ट रूप से कार्यकर्ता धागे से LoadProperty बुला ... के अलावा अन्य): मैं VS2010 का उपयोग कर रहा है, इसलिए यह एफई 4.0 है। मुझे नहीं पता कि यह ईएफ के पिछले संस्करण में समान था ...

+1

मुझे आपकी प्रेरणा के बारे में निश्चित नहीं है, लेकिन .NET टीम थ्रेड पूल के स्पष्ट उपयोग के बजाय कार्य और कार्य के साथ कोड को प्रोत्साहित करने के लिए प्रोत्साहित करती है। शायद कोई उस का एक अच्छा उद्धरण प्रदान कर सकता है? –

+0

क्या आप थोड़ा 'पी 2' के उपयोग पर विस्तार कर सकते हैं? मुझे लगता है कि यह कुछ भी नहीं बदला है? –

+0

@jarrett: शायद, लेकिन यह बात नहीं है ... समस्या एक कार्य के साथ समान होती, क्योंकि यह वैसे भी धागे का उपयोग करती है। @ हेनक: यह 'पी 2' के बिना या तो काम नहीं करता है, लेकिन वैसे भी यह आवश्यक है, अन्यथा प्रत्येक लैम्ब्डा एक ही चर पर बंद हो जाएगा; विवरण के लिए यह आलेख देखें: http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-Considered-harmful.aspx –

उत्तर

7

क्या यह डिज़ाइन द्वारा है? हाँ; लोड, निहित या स्पष्ट करने के लिए कोई भी कॉल अंततः ObjectContext, और ObjectContext is documented to be not thread-safe के माध्यम से जाएगा।

कार्यकर्ता धागे में ऑब्जेक्ट संदर्भ से इकाई को अलग करने और वर्तमान धागे में किसी ऑब्जेक्ट संदर्भ से अटैचमेंट करने के लिए एक संभावित कार्यवाही होगी।

+0

आपके उत्तर के लिए धन्यवाद। दुर्भाग्यवश, मेरे मामले में एक और ऑब्जेक्ट संदर्भ बनाना निश्चित रूप से अधिक है। मैं एक एसिंक बाध्यकारी का उपयोग कर एक WPF अनुप्रयोग में छवियों को लोड करने की कोशिश कर रहा हूं, और मैं वास्तव में प्रत्येक छवि के लिए एक नया संदर्भ नहीं बनाना चाहता (वर्तमान में लगभग 150 छवियां) –

+0

मुझे लगता है कि इस बिंदु पर आपके पास एक WPF प्रश्न है , एक ईएफ सवाल नहीं। ईएफ के नियम बहुत सरल हैं। WPF का उपयोग करके उनका अनुसरण कैसे करें एक और मुद्दा है। –

+0

ठीक है, मैं इसे WPF में उपयोग कर रहा हूं, लेकिन यह एक WPF- विशिष्ट समस्या नहीं है। और दस्तावेज में थ्रेडिंग के बारे में एकमात्र चीज सामान्य "थ्रेड सुरक्षा" जानकारी है जो लगभग सभी वर्गों के लिए समान है। यह कहता है * थ्रेड सुरक्षित होने की गारंटी नहीं है *, नहीं * एकाधिक धागे * द्वारा उपयोग नहीं किया जा सकता है। थ्रेड सुरक्षित नहीं होने का मतलब यह नहीं है कि आप बहु थ्रेडिंग का उपयोग नहीं कर सकते हैं, इसका मतलब है कि आपको सिंक्रनाइज़ेशन स्वयं को संभालना होगा। –

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