2012-01-17 4 views
6

मैं अपने व्यू मॉडल्स (सिल्वरलाइट और/या डब्ल्यूपी 7 ऐप्स) में आसान ईवेंट हैंडलिंग के लिए प्रतिक्रियाशील एक्सटेंशन का उपयोग कर रहा हूं। के सरलता के जाने के लिए कहते हैं कि मैं अपने वीएम की ctor में इस तरह की एक पंक्ति है:IObservers का निपटारा करने के साथ क्या करना है?

Observable.FromEvent<PropertyChangedEventArgs>(
          h => MyObject.PropertyChanged += h, 
          h => MyObject.PropertyChanged -= h) 
    .Where(e=>e.PropertyName == "Title") 
    .Throttle(TimeSpan.FromSeconds(0.5)) 
    .Subscribe(e=>{/*do something*/}); 

यह एक IDisposable वस्तु, जो यदि निपटारा सदस्यता समाप्त कर देगा देता है।(क्या मैं इस धारणा में सही हूं?)
यदि मेरे पास इसका कोई संदर्भ नहीं है, तो जल्दी या बाद में इसे एकत्र किया जाएगा, और मेरे हैंडलर की सदस्यता समाप्त हो जाएगी।

मेरे पास आमतौर पर मेरे वीएम में List<IDisposable> है, और मैं इसके लिए सब्सक्रिप्शन जोड़ता हूं, फिर भी मुझे इसके बारे में गंदा लगता है, जैसे कि मैं सही आरएक्स तरीके से कुछ नहीं कर रहा हूं।

सबसे अच्छा अभ्यास है, इस तरह की स्थितियों पर सिफारिश पैटर्न क्या है?

उत्तर

9

आपका पहला धारणा सही है, IDisposable सदस्यता त्यागने की प्रक्रिया के लिए है। हालांकि, आपको अपने पर्यवेक्षक को एकत्र होने से रोकने के लिए IDISposable का संदर्भ रखने की आवश्यकता नहीं है। IObservable को पर्यवेक्षक को इसके तरीकों को कॉल करने में सक्षम होने के लिए संदर्भ रखना होगा, इस प्रकार पर्यवेक्षक जीवित रहेंगे जब तक कि अवलोकन योग्य जीवित न हो।

चतुर पाठक, एहसास होगा कि मैं कुछ सवाल भीख माँग रहा हूँ, क्योंकि मैं मान लिया है कि नमूदार एकत्र नहीं किया जाएगा। उस मुद्दे से निपटने के लिए, चलो दृश्यों के पीछे क्या हो रहा है इसके बारे में कुछ उचित अनुमान लगाएं। पहला अवलोकन एक घटना की सदस्यता ले रहा है। इसका अर्थ यह है कि घटना के साथ ऑब्जेक्ट हमारे पर्यवेक्षक का संदर्भ है जब तक हम सदस्यता समाप्त करते समय सदस्यता लेते हैं। चूंकि आरएक्स ऑपरेटरों को किसी बिंदु पर अपने स्रोतों की सदस्यता लेनी चाहिए, इसलिए कोई यह मान सकता है कि ईवेंट पर्यवेक्षक के पास कहां पर्यवेक्षक का संदर्भ है, जिसमें थ्रॉटल पर्यवेक्षक का संदर्भ है, जो निश्चित रूप से हमारे अंतिम पर्यवेक्षक का जिक्र कर रहा है।

जब से हम सदस्यता समाप्त करने का कोई तरीका नहीं रखा, इस घटना के साथ वस्तु के जीवन के लिए पर्यवेक्षक की जीवन बांध। आपके कार्यक्रम के पूर्ण ज्ञान के बिना, यह वह श्रृंखला है जो मैं जा सकता हूं, लेकिन मुझे लगता है कि यह देखने योग्य के जीवनकाल को निर्धारित करने के लिए आपके लिए पर्याप्त होना चाहिए।

यह वास्तव में एक संभावित "स्मृति रिसाव" आप मानक नेट घटनाओं, अपने सभी घटना ग्राहकों को जीवित रखने वस्तुओं, जो आपके दूसरे प्रश्न की ओर जाता है के साथ हो सकता है बताते हैं। यदि आप IDISposable का संदर्भ नहीं रखते हैं, तो आप कभी भी ईवेंट से सदस्यता समाप्त नहीं कर पाएंगे और आपके ऑब्जेक्ट को नोटिस प्राप्त करना जारी रहेगा, भले ही आप उस दृश्य को बंद कर दें, इससे संबंधित है। यदि ईवेंट स्रोत दृश्य से अधिक समय तक नहीं रहता है, तो यह कोई समस्या नहीं हो सकती है, लेकिन मैं डिस्पोजेबल का उपयोग करने की अनुशंसा करता हूं।

इसके बारे में "अन-आरएक्स" कुछ भी नहीं है, और यदि आप चाहते हैं, तो 0xमें आरएक्स सूची के विकल्प के रूप में उपयोग करने के लिए एक अच्छी कक्षा भी शामिल है।

+0

मुझे .NET मेमोरी इवेंट रिसाव के बारे में पता है, फिर भी मैंने इस तथ्य को छोड़ दिया कि इससे कोई फर्क नहीं पड़ता कि IObservable पर्यवेक्षकों को अंतिम रूप देने पर निपटाता है, क्योंकि अंतिम रूप यहां कॉल नहीं किया जाता है ... धन्यवाद! – TDaver

+1

यदि मैं निर्दिष्ट कर रहा था कि 'IObservable ' व्यवहार करना चाहिए और इसका उपयोग किया जाना चाहिए, तो मैं यह निर्दिष्ट करता हूं कि प्रत्येक उचित रूप से लिखित उपभोक्ता को किसी भी स्थान पर वापस 'आईडीस्पोजेबल' का संदर्भ रखना चाहिए, और कार्यान्वयन को स्वयं को स्वतंत्र मानना ​​चाहिए (यदि प्रोत्साहित नहीं किया जाता है) किसी भी सदस्यता को रद्द करें जिसका संबद्ध 'आईडीस्पोजेबल' गुंजाइश से बाहर हो गया। – supercat

-1

सामान्य अभ्यास IDisposable इंटरफ़ेस को कार्यान्वित करना और यहां अपने डिस्पोजेबल सदस्यों का निपटान करना है।

+0

क्या आपका मतलब है कि मेरा वीएम कार्यान्वयन योग्य है? उस पर निपटान कौन करेगा?(या क्या मुझे अंतिमकर्ता के साथ एक निपटान-पैटर्न लागू करना चाहिए?) – TDaver

+0

@TDaver यह ग्राहक को 'निपटान' कहने के लिए जिम्मेदार है, इसलिए यह इस बात पर निर्भर करता है कि आप अपनी ऑब्जेक्ट को कैसे चालू करते हैं। –

6

गिदोन यहाँ सही नहीं है। आरएक्स IDISposable का उपयोग करने के अर्थशास्त्र सामान्य .NET से अलग हैं। सदस्यता से लौटाया गया IDISposable है यदि आप IObservable के अंत से पहले सदस्यता समाप्त करना चाहते हैं। यदि आप ऐसा नहीं करना चाहते हैं, तो सभी अतिरिक्त डिस्पोजेबल प्रबंधन के साथ अपने कोड को जटिल बनाना अनावश्यक है।

+0

तो अगर मेरा इवेंटसोर्स ऑनकंपेटेड बढ़ाता है, तो सबकुछ स्वचालित रूप से सदस्यता समाप्त हो जाएगा? – TDaver

+0

टीडीवर: हाँ यह –

+0

हाँ होगा लेकिन "ईवेंट" कभी पूरा नहीं होगा। यह अवलोकन धाराओं और पसंद का उपयोग करने के लिए है। इसलिए मुझे गिडोन के विचार की आवश्यकता है, जबकि आप भी स्पष्ट रूप से सही हैं ... – TDaver

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