2010-05-27 8 views
9

मैं हाल ही में मेमोरी मैनेजमेंट में देख रहा हूं और यह देख रहा हूं कि ईवेंट कैसे प्रबंधित किए जाते हैं, अब, मैं ईवेंट सदस्यता के लिए स्पष्ट ऐड/हटा वाक्यविन्यास देख रहा हूं।स्पष्ट घटना जोड़ें/हटाएं, गलत समझा?

मुझे लगता है कि यह बहुत आसान है, अगर मैं सदस्यता लेता हूं और सदस्यता छोड़ता हूं तो मुझे अन्य तर्क करने की अनुमति देता है? क्या मैं इसे प्राप्त कर रहा हूं, या इसके लिए और कुछ है?

इसके अलावा, जब मैं यहां हूं, तो मेरे ईवेंट हैंडल को साफ करने के लिए कोई सलाह/सर्वोत्तम प्रथाएं।

उत्तर

3

वाक्यविन्यास जोड़ें/निकालें आमतौर पर किसी अन्य वर्ग में किसी ईवेंट कार्यान्वयन को "आगे" करने के लिए उपयोग किया जाता है।

सब्सक्रिप्शन साफ़ करना ("ईवेंट हैंडल" नहीं) IDisposable लागू करके सबसे अच्छा किया जाता है।

अद्यतन: कुछ भिन्नता है जिस पर ऑब्जेक्ट IDisposable लागू करना चाहिए। आरएक्स टीम ने डिजाइन परिप्रेक्ष्य से सबसे अच्छा निर्णय लिया: सदस्यता स्वयं IDisposable हैं। नियमित .NET ईवेंट में ऐसी ऑब्जेक्ट नहीं होती है जो सदस्यता का प्रतिनिधित्व करती है, इसलिए पसंद प्रकाशक (जिस वर्ग पर ईवेंट परिभाषित किया गया है) और ग्राहक (आमतौर पर वह वर्ग जिसमें सदस्य फ़ंक्शन सब्सक्राइब किया जाता है) के बीच होता है। जबकि मेरे डिजाइन प्रवृत्त ग्राहक IDisposable बनाने के लिए पसंद करते हैं, अधिकांश वास्तविक दुनिया कोड प्रकाशक IDisposable बनाता है: यह एक आसान कार्यान्वयन है, और ऐसे मामले हो सकते हैं जहां वास्तविक ग्राहक उदाहरण नहीं है।

(यही कारण है, अगर कोड वास्तव में बिल्कुल भी घटना सदस्यता को साफ है। अधिकांश कोड ऐसा नहीं करता।)

+0

हा, मैं उन्हें अपने सहयोगियों से बात करते समय सब्सक्रिप्शन के रूप में संदर्भित करता हूं, फिर भी जब मैं कोई प्रश्न पोस्ट करता हूं, तो मैं गलत शब्दावली का उपयोग कर रहा हूं। स्पष्टीकरण के लिए धन्यवाद। – Hammerstein

6

हाँ, जोड़ें/वाक्य रचना को दूर आप अपने खुद के सदस्यता तर्क लागू करने के लिए अनुमति देता है। जब आप उन्हें छोड़ देते हैं (किसी ईवेंट के लिए मानक नोटेशन) संकलक मानक कार्यान्वयन उत्पन्न करता है। यह ऑटो-गुणों की तरह है।

निम्नलिखित नमूने में, Event1 और Event2 के बीच कोई वास्तविक अंतर नहीं है।

public class Foo 
{ 
    private EventHandler handler; 
    public event EventHandler Event1 
    { 
    add { handler += value; } 
    remove { handler -= value; } 
    } 

    public event EventHandler Event2; 
} 

लेकिन यह 'सफाई' हैंडलर से एक अलग विषय है। यह सब्सक्राइबिंग क्लास है जो सदस्यता रद्द करनी चाहिए। प्रकाशन वर्ग इस के साथ बहुत मदद नहीं कर सकता है।
ऐसी कक्षा की कल्पना करें जो इसकी घटनाओं की सदस्यता सूची को 'साफ' करेगी। जब यह स्वयं को विघटित किया जाता है तो यह केवल समझदारी से ऐसा कर सकता है, और फिर यह उत्पादक होने की संभावना नहीं है क्योंकि एक विघटित वर्ग आमतौर पर इसे विस्थापित होने के तुरंत बाद एकत्रित हो जाती है।

+1

मुझे विश्वास है कि एक अंतिम उपयोगकर्ता नहीं कर सका: 'Foo foo = ...; foo.Event1 (प्रेषक, ई); 'लेकिन कर सकता है 'foo.Event2 (शून्य, शून्य);'। – user7116

+0

उदाहरण और स्पष्टीकरण के लिए धन्यवाद। मैंने सोचा कि मेरे पास था, लेकिन मैं इसे सोच रहा था! मैं अपना प्रश्न स्मृति प्रबंधन पर एक अलग प्रश्न में पोस्ट करूंगा, क्योंकि मुझे लगता है कि मैं और पूछना चाहता हूं। – Hammerstein

+0

मुझे गलती है, आपको दोनों मामलों में एक त्रुटि प्राप्त होती है, लेकिन आपको दूसरे मामले में एक अलग मिलता है, 'त्रुटि CS0070: ईवेंट' Program.Foo.Event2 'केवल + = या बाईं ओर बाईं ओर दिखाई दे सकता है - = (जब 'प्रोग्राम.फू' प्रकार के भीतर से उपयोग किया जाता है) '। – user7116

9

जोड़ें/निकालें गुण मूल रूप से अन्य सदस्यों के साथ सेट/प्राप्त गुणों का उपयोग करने के समान तर्क के मूल तर्क हैं। यह किसी ईवेंट के लिए पंजीकरण करते समय आपको कुछ अतिरिक्त तर्क बनाने की अनुमति देता है, और ईवेंट को स्वयं को समाहित करता है।

आप इसे क्यों करना चाहते हैं, इसके लिए एक अच्छा उदाहरण है, जब इसकी आवश्यकता नहीं होती है तो अतिरिक्त गणना को रोकना है (कोई भी घटना को सुन नहीं रहा है)।

उदाहरण के लिए, मान लीजिए कि घटनाओं एक टाइमर से शुरू हो रहा है, और हम अगर कोई घटना के लिए पंजीकृत है टाइमर काम करने के लिए नहीं करना चाहती:

private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); 
private EventHandler _explicitEvent; 
public event EventHandler ExplicitEvent 
{ 
    add 
    { 
     if (_explicitEvent == null) timer.Start(); 
     _explicitEvent += value; 
    } 
    remove 
    { 
     _explicitEvent -= value; 
     if (_explicitEvent == null) timer.Stop(); 
    } 
} 

आप शायद करना चाहते हैं किसी ऑब्जेक्ट (एक बाद विचार) के साथ जोड़ें/निकालें लॉक करें ...

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