2012-01-09 18 views
11

मैं जो मेरे प्रिज्म आवेदन में स्मृति लीक का कारण बनता है MEF की ओर से जीवन में किसी समस्या के कुछ हद तक सामना किया है से एकत्र होने के लिए।MEF NonShared IDisposable भागों के संदर्भ रहता है, की अनुमति नहीं दे उन्हें जीसी

PartCreationPolicy के साथ मेरा आवेदन निर्यात दृश्य और दृश्य मॉडल CreationPolicy.NonShared पर सेट किया जा रहा है। विचारों और ViewModels क्रमशः ViewBase और ViewModelBase से विरासत है, जो IDisposable लागू करता है।

अब, चूंकि मेरे हिस्से IDisposable लागू करते हैं, इसलिए उनके संदर्भ में कंटेनर रखा जाता है, जिससे उन्हें कचरा कलेक्टर द्वारा रिहा नहीं किया जाता है। MEF documentation on part lifetime के अनुसार, इस डिजाइन के द्वारा होता है:

कंटेनर भागों के लिए संदर्भ में यह बनाता है पकड़ नहीं होगा जब तक निम्न में से एक सत्य है:

  • हिस्सा Shared
  • भाग के रूप में चिह्नित किया गया है लागू IDisposable
  • एक या अधिक आयात recomposition
अनुमति देने के लिए कॉन्फ़िगर किया गया है

मैं MEF इन भागों के लिए एक संदर्भ नहीं रख कैसे तो कर सकते हैं? क्या कोई विशेषता है जिसका उपयोग मैं एमईएफ को यह बताने के लिए कर सकता हूं कि मैं नहीं चाहता कि यह मेरे हिस्से का संदर्भ रखे, भले ही यह IDisposable लागू करता हो?

रणनीतियों ऊपर लेख में चर्चा के दोनों मेरे लिए अच्छा समाधान की तरह लग नहीं है:

  • ReleaseExport एक पैरामीटर है, जो मैं कैसे प्रदान करने के लिए पता नहीं है के रूप में एक Export वस्तु की आवश्यकता है। मेरे पास मेरे विचार का उदाहरण है, लेकिन मेरे पास यह जानने का कोई तरीका नहीं है कि दृश्य बनाने के लिए इस्तेमाल किया गया अनुबंध क्या था। ReleaseExport के लिए अधिभार होने पर यह बहुत अच्छा होगा, जो कंटेनर द्वारा बनाई गई किसी ऑब्जेक्ट को प्राप्त कर सकता है।
  • एक बच्चे कंटेनर का उपयोग करते हुए एक प्राकृतिक विकल्प की तरह या तो प्रतीत नहीं होता।

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

उत्तर

7

जब तक प्रिज्म दृश्य वस्तुओं के लिए जीवन भर किसी तरह का समर्थन करता है, वहाँ के लिए छोड़कर यहाँ कोई समाधान नहीं है दृश्य द्वारा उजागर इंटरफेस की सूची से IDisposable हटाएं।

इस समस्या से निपटने के लिए तीन MEF दृष्टिकोण रहे हैं, अन्य सभी प्रतिसाददाताओं ने उल्लेख किया:

  • ExportFactory<T>
  • बाल कंटेनर
  • ReleaseExport()

वे सब के सब पर कुछ काम की आवश्यकता होती है उस कोड का हिस्सा जो मूल निर्यात का अनुरोध करता है - इस मामले में प्रिज्म के भीतर कोड। यह कुछ समझ में आता है, क्योंकि किसी वस्तु को उपभोग करने वाले कोड के लिए यह अवांछनीय है कि इसे कैसे और कब बनाया गया था, इस बारे में जागरूक होना चाहिए।

एमईएफ में ReleaseExportedObject() नहीं है क्योंकि एकाधिक (उदा। संपत्ति) निर्यात एक ही मूल्य वापस कर सकते हैं; यह प्रदान करने के लिए तर्कसंगत रूप से संभव हो सकता है लेकिन अतिरिक्त जटिलता ने भविष्य में एमईएफ द्वारा संबोधित किए जाने की संभावना नहीं बनाई है।

उम्मीद है कि इससे मदद मिलती है; मैंने इस प्रश्न 'प्रिज्म' को दोबारा हासिल कर लिया है क्योंकि मुझे यकीन है कि प्रिज्म समुदाय के अन्य लोगों ने इसका सामना किया होगा और सलाह देने में सक्षम होंगे।

+0

उत्तर के लिए धन्यवाद और स्वागत retag के लिए धन्यवाद। मुझे लगता है कि 'निर्यात फैक्ट्री' के साथ प्रिज्म के साथ एकीकरण सही तरीका है, हालांकि यह एक सरल अनुरोध के लिए ओवरकिल जैसा लगता है "मुझे कंटेनर में शामिल न करें"। मैंने अभी तक नहीं छोड़ा है - मैं अभी भी इसके लिए एक और सरल और सुरुचिपूर्ण समाधान ढूंढ रहा हूं। –

5

जब आप IDisposable आप एक तरह से कह रहे हैं कि प्रकार एक नियतात्मक प्रकार से साफ किया जाना चाहिए लागू (

आपके मामले में दृश्य IDisposable.Dispose फोन करके और बेतरतीब ढंग से नहीं जब कचरा कलेक्टर फैसला करता है कि यह समय है। मॉडल केवल निपटारा किया जाएगा जब आप कंटेनर जो शायद नहीं है कि आप क्या करना चाहते हैं निपटाने इस के आसपास पाने के लिए मैं दो संभव समाधान देखें:।।

  • आपके विचार मॉडल पर IDisposable को लागू न करें जाहिरा तौर पर आप डॉन जब भी वे साफ हो जाते हैं तब तक परवाह नहीं करते हैं उन्हें IDisposable क्यों बनाएं?

  • इसके बजाय दे कंटेनर प्रत्येक दृश्य मॉडल बनाने की गैर साझा आप एक साझा दृश्य मॉडल कारखाने वर्ग इस्तेमाल कर सकते हैं। फिर आप उस वर्ग को दृश्य मॉडल के मालिकों में इंजेक्ट कर सकते हैं ताकि मालिकों को स्पष्ट रूप से दृश्य मॉडल बनाने की अनुमति मिल सके। संभवतः इन मालिकों को यह भी पता चलेगा कि दृश्य मॉडल का निपटान कब किया जाए।

असल में, यदि कुछ डिस्पोजेबल है तो आपके कोड में एक समझदार बिंदु भी होना चाहिए जहां आपको डिस्पोजेबल का निपटान करने की आवश्यकता है।

+0

मेरा मानना ​​है कि आप इस बात से सहमत होंगे कि यह मूर्खतापूर्ण है कि मैं जल्द से जल्द किसी ऑब्जेक्ट का निपटान करने के लिए 'आईडीस्पोजेबल' लागू करता हूं, और एमईएफ कंटेनर के कार्यान्वयन के कारण सटीक विपरीत प्राप्त करता हूं। मेरे वीएम पर 'आईडीस्पोजेबल' लागू नहीं करना एक वास्तविक विकल्प नहीं है क्योंकि मुझे समग्र कमांड से अनियंत्रण की तरह क्लीनअप करने की आवश्यकता है - अगर मैं ऐसा नहीं करता, तो वीएम जीसीडी नहीं होंगे। मेरे विचार उनके वीएम का निपटान करने के प्रभारी हैं, लेकिन 'निपटान()' को कॉल करने का कोई भी तरीका कंटेनर से ऑब्जेक्ट के संदर्भ को नहीं हटाता है, जिससे कि वैसे भी मदद नहीं मिलती है। –

+0

मुझे लगता है कि एमईएफ द्वारा बनाए गए मॉडल को देखने के बजाय प्रत्येक दृश्य में एक दृश्य मॉडल कारखाने को इंजेक्शन देने के अपने दूसरे सुझाव का उपयोग करके अपनी समस्या का समाधान करना चाहिए। स्पष्ट रूप से प्रत्येक दृश्य मॉडल के लिए एक कारखाना बनाना बल्कि कठिन हो जाता है लेकिन फिर भी मैं निर्भरता इंजेक्शन के लिए एमईएफ के वर्तमान संस्करण का उपयोग करते समय खुद को बहुत कुछ कर रहा हूं। –

4

आपको इन उदाहरणों को आयातित ExportFactory<T> के माध्यम से बनाना चाहिए। उसके बाद ExportLifetimeContext<T>.Dispose() के माध्यम से उन्हें निपटाने के लिए आवश्यक नियंत्रण होगा।

हालांकि, यह केवल अगले .NET संस्करण (4.5) में बॉक्स के बाहर या कोडप्लेक्स पर नवीनतम MEF पूर्वावलोकन रिलीज़ में उपलब्ध है। (MEF के पुराने संस्करणों में ही कार्यक्षमता इस blog post में वर्णित के रूप में एक नमूना के रूप में लागू किया गया था और PartCreator बुलाया गया था,।)

+0

मैंने अपने प्रश्न में इसका जिक्र नहीं किया, लेकिन मैं अपने विचार बनाने के लिए प्रिज्म का उपयोग कर रहा हूं, इसलिए मैं वास्तव में 'ExportFactory' ऑब्जेक्ट को पुनर्प्राप्त करने के लिए कोड के उस हिस्से तक नहीं पहुंच सकता। यहां तक ​​कि अगर मैं कर सकता था, तो कोड में उस जगह से फैक्ट्री ऑब्जेक्ट तक पहुंचने की समस्या है जहां मैं दृश्य का निपटान करना चाहता हूं, और प्रत्येक 'गैर-साझा' ऑब्जेक्ट के लिए 'निर्यात फैक्ट्री' का उपयोग करना जो बहुत ही अनजान है और ऐसा नहीं लगता है एक अच्छा अभ्यास। –

+0

@ लेस्टर: आपको केवल उन वस्तुओं के लिए ExportFactory का उपयोग करना चाहिए जिन्हें आयातक द्वारा स्पष्ट रूप से बनाया/डिस्पोजेड किया जाना चाहिए (जो एमईएफ कंटेनर की तुलना में कम जीवन काल के साथ वस्तुओं के निर्माण को सक्षम बनाता है)। मैं ** ** नहीं कह रहा हूं कि जहां भी आपके पास नॉनशेयर निर्यात है, तो आपको ExportFactory का उपयोग करना चाहिए। –

2

अन्य सभी उत्तरों इस मुद्दे को रोकने के लिए अच्छे तरीके प्रदान करते हैं, लेकिन अंततः मैं जो कर रहा हूं वह IDisposable के बजाय अपने स्वयं के कस्टम इंटरफ़ेस, ICleanup का उपयोग कर रहा था। यह निश्चित रूप से सभी के लिए उपयुक्त नहीं हो सकता है।

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

  • कोई संबंधित समस्या नहीं^_^