2009-10-08 27 views
44

निष्पादित करने से पहले डिस्पोज़ करता है मैंने एक विशिष्ट फ़ाइल पर बने रहने के लिए अपनी खुद की कस्टम डेटा परत लिखी है और मैंने इसे कस्टम डेटाकॉन्टेक्स्ट पैटर्न के साथ सारणीबद्ध किया है।उपयोग() {} ब्लॉक के अंदर उपज रिटर्न स्टेटमेंट

यह सभी .NET 2.0 फ्रेमवर्क (लक्ष्य सर्वर के लिए बाधाओं को देखते हुए) पर आधारित है, हालांकि यह कुछ LINQ-to-SQL की तरह दिख सकता है, इसकी नहीं! मैंने अभी एक समान डेटा पैटर्न लागू किया है।

ऐसी स्थिति के उदाहरण के लिए नीचे उदाहरण देखें जो मैं अभी तक समझा नहीं सकता।

पशु की सभी आवृत्तियों प्राप्त करने के लिए - मैं यह करने के लिए और इसे

public IEnumerable<Animal> GetAllAnimals() { 
     foreach (var animalName in AnimalXmlReader.GetNames()) 
     { 
      yield return GetAnimal(animalName); 
     } 
} 

AnimalDataContext नीचे AnimalDataContext() में ठीक

public static IEnumerable<Animal> GetAllAnimals() { 
     AnimalDataContext dataContext = new AnimalDataContext(); 
      return dataContext.GetAllAnimals(); 
} 

और GetAllAnimals के कार्यान्वयन() विधि काम करता है () IDISposable लागू करता है क्योंकि मुझे वहां XmlTextReader मिला है और मैं यह सुनिश्चित करना चाहता हूं कि यह जल्दी से साफ हो जाए।

अब अगर मैं इतना

public static IEnumerable<Animal> GetAllAnimals() { 
     using(AnimalDataContext dataContext = new AnimalDataContext()) { 
      return dataContext.GetAllAnimals(); 
     } 
} 

की तरह एक बयान का उपयोग कर के अंदर पहली कॉल लपेट और (पहली बार में AnimalDataContext.GetAllAnimals की पहली पंक्ति में एक को तोड़ने सूत्री डाल) विधि और एक अन्य को तोड़ने बिंदु विधि AnimalDataContext.Dispose() में लाइन, और निष्पादित ...

निपटान() विधि सबसे पहले कहा जाता है ताकि AnimalXmlReader.GetNames() देता है "ऑब्जेक्ट संदर्भ ऑब्जेक्ट की उदाहरण के लिए सेट नहीं" अपवाद क्योंकि AnimalXmlReader है निपटान में शून्य करने के लिए सेट किया गया है() ???

कोई विचार? मैं एक कूबड़ है कि इससे संबंधित करने के लिए उपज वापसी एक कोशिश कैच ब्लॉक के अंदर कहा जा करने की अनुमति नहीं किया जा रहा है, जो का उपयोग कर प्रभावी ढंग से प्रतिनिधित्व करता है, एक बार संकलित ...

+0

यह मूलतः समस्याओं मैं का सामना किया है में से एक है, यहाँ मेरे सवाल देखें:: इस तरह ब्लॉक का उपयोग आप तक बंद नहीं किया जाएगा कि प्रगणक का उपयोग बंद http://stackoverflow.com/questions/1524367 –

उत्तर

50

जब आप GetAllAnimals फोन यह वास्तव में ऐसा नहीं करता है जब तक आप फ़ोरैच लूप में लौटाए गए IENumerable की गणना नहीं करते हैं तब तक किसी भी कोड को निष्पादित करें।

आईन्यूमेरेबल की गणना करने से पहले, डेटा कॉन्टेक्स्ट को रैपर विधि के रूप में जल्द ही डिस्पोजेक्ट किया जा रहा है।

सरल समाधान के आवरण विधि पुनरावर्तक के साथ-साथ बनाने के लिए, इस तरह होगा:

public static IEnumerable<Animal> GetAllAnimals() { 
    using (AnimalDataContext dataContext = new AnimalDataContext()) { 
     foreach (var animalName in dataContext.GetAllAnimals()) { 
      yield return GetAnimal(animalName); 
     } 
    } 
} 

इस तरह, कथन का उपयोग बाहरी इटरेटर में संकलित किया जाएगा, और यह केवल जब निपटारा किया जाएगा बाहरी इटरेटर का निपटारा किया जाता है।

एक और समाधान रैपर में आईनेमेरेबल को गिनना होगा। ऐसा करने के लिए सबसे आसान तरीका है एक List<Animal> वापस जाने के लिए, इस तरह होगा:

public static IEnumerable<Animal> GetAllAnimals() { 
    using (AnimalDataContext dataContext = new AnimalDataContext()) { 
     return new List<Animal>(dataContext.GetAllAnimals()); 
    } 
} 

ध्यान दें कि यह आस्थगित निष्पादन के लाभ खो देता है, तो भले ही आप उन्हें जरूरत नहीं है यह जानवरों के सभी मिल जाएगा।

+1

धन्यवाद स्लाक्स - दूसरा विकल्प चाल और इसकी साफ-सुथरा रेखाओं की कम लाइनें, कम बग! वह कॉल "AnimalDataContextAdapter" में जा रही है जो वेबफॉर्म प्रोजेक्ट के लिए प्रेजेंटेशन लेयर में बैठती है - विशेष रूप से संग्रह को गणना करने के लिए, इसलिए स्थगित निष्पादन पर कोई वास्तविक हानि नहीं है। –

+0

मैं इसे इस प्रकार समझाऊंगा: 'उपज वापसी' या अन्य निष्पादन निष्पादन विधियों का उपयोग करने वाले तरीकों में आईडीस्पोजेबल पैरामीटर को कभी स्वीकार न करें –

+0

'उपज रिटर्न' के साथ उपयोग सुरक्षित है और कॉल आपकी स्ट्रीम [IFF] (https: // www पर निपटान करें। google.com/search?q=define%20iff) संग्रह पूरी तरह से गणना की गई है। http://blogs.msdn.com/b/dancre/archive/2008/03/14/yield-and-usings-your-dispose-may-not-be-called.aspx – yzorg

10

इसका कारण यह है कि GetAllAnimals विधि जानवरों के कोलेसिटन को वापस नहीं करती है। यह एक गणक देता है जो एक समय में एक जानवर को वापस करने में सक्षम है।

जब आप उपयोग ब्लॉक के अंदर GetAllAnimals कॉल से परिणाम वापस करते हैं, तो आप केवल गणनाकर्ता को वापस कर देते हैं। विधि का उपयोग करने से पहले उपयोग ब्लॉक डेटा संदर्भ को निपटाता है, और उस बिंदु पर गणनाकर्ता ने अभी तक किसी भी जानवर को नहीं पढ़ा है। जब आप गणनाकर्ता का उपयोग करने का प्रयास करते हैं, तो यह किसी भी जानवर को डेटा संदर्भ से नहीं प्राप्त कर सकता है।

GetAllAnimals विधि भी एक गणक बनाने के लिए एक कामकाज है। साथ ही

public static IEnumerable<Animal> GetAllAnimals() { 
    using(AnimalDataContext dataContext = new AnimalDataContext()) { 
     foreach (Animal animal in dataContext.GetAllAnimals()) { 
     yield return animal; 
     } 
    } 
} 
संबंधित मुद्दे