2009-11-27 20 views
12

ट्रिगर नहीं किया गया है मैं प्रिज्म के साथ एक ईवेंट एकत्रीकरण को लागू करने पर काम कर रहा हूं। मेरे पास कुछ मॉड्यूल हैं, और मैं चाहता हूं कि उनमें से प्रत्येक घटनाओं की सदस्यता लें जो उन्हें अनुरोध करते समय बताए। मैंने खोल में सब्सक्राइब और प्रकाशक दोनों के साथ एक सादा उदाहरण शुरू कर दिया। वहां कोई समस्या नहीं है। अभी व; जब मैं ग्राहकों को अपने मॉड्यूल में ले जाता हूं तो वे ट्रिगर नहीं होते हैं। और भी अजीब बात यह है कि यह वास्तव में कुछ बार काम करता है - जिनमें से सभी को ब्रेकपॉइंट में लंबित किया गया है। तो मुझे लगता है कि मुझे कुछ दौड़ की स्थिति है, लेकिन मुझे समझ में नहीं आता क्यों।प्रिज्म इवेंट एकत्रीकरण - ग्राहक

अनुमान लगाया गया: मुझे कहीं भी आईवेन्टएग्रेगेटर सेट अप करने की आवश्यकता नहीं है - उदा। आईओसी कंटेनर में पंजीकरण? यह प्रिज्म में बनाया गया है कि मेरे पास केवल ईवेंट एग्रीगेटर का एक उदाहरण है, है ना?

तो, सवाल मूल रूप से कैसे/कहाँ/जब मुझे अपने ग्राहकों को स्थापित करना चाहिए। सामान आदि पर एक विशिष्ट आदेश है? मेरे सरलीकृत उदाहरण में मेरे पास एक मॉड्यूल MyModule है। Bootstrapper सूची को MyModule जोड़ना होगा - यह प्रारंभ बनाने:

catalog.AddModule(typeof(MyModule)); 

MyModule एग्रीगेटर की दुकान और MyModuleRequestedEvent की सदस्यता के लिए इस का उपयोग करेगा। यह एप्लिकेशन मेनू में पंजीकरण के लिए मेनू रजिस्ट्री का भी उपयोग करता है। विचार यह है कि अंततः मेनू में क्लिक करने से ईवेंट ट्रिगर होना चाहिए - MyModule को सूचित करना कि अनुरोध किया गया है। तो मैं यह जानना चाहता हूं कि आगे क्या करना है यह जानने के लिए यह MyModule की ज़िम्मेदारी है।

public MyModule(IEventAggregator aggregator, IApplicationMenuRegistry menu) 
{ 
    _applicationMenu = menu; 
    _aggregator = aggregator; 
} 

public void Initialize() 
{ 
    var evnt = _aggregator.GetEvent<MyModuleRequestedEvent>(); 
    evnt.Subscribe(MyModuleRequested); 
    _applicationMenu.RegisterMenuItem("MyModule", evnt); 
} 

public void MyModuleRequested(bool b) 
{ 
    MessageBox.Show("MyModule requested"); 
} 

अब, मेरे पास मेरे खोल में एक बटन है जो इस घटना को प्रकाशित करेगा। हल होने पर खोल को वही (?) ईवेंट एग्रीगेटर मिल जाता है।

public Shell(IEventAggregator aggregator) 
{ 
    InitializeComponent(); 
    var evnt = aggregator.GetEvent<MyModuleRequestedEvent>(); 
    EventTriggerButton.Click += (s, e) => evnt.Publish(true); 
} 

नोट्स:

  • जांच लिया है कि घटना प्रकाशित हुआ है। खोल में एक ग्राहक जोड़ना भी इस ग्राहक को घटना प्राप्त करेगा।
  • फिर से; MyModule में ग्राहक ट्रिगर नहीं किया गया है। हालांकि, यह आश्चर्यजनक रूप से - कुछ मौकों पर रहा है।
  • मैं इस कार्यक्रम में इनपुट का उपयोग नहीं करता हूं। ऐसा लगता है कि आपको कुछ इनपुट-प्रकार रखने की आवश्यकता है, इसलिए मैं बस एक डमी बूल के साथ गया। क्या मैं इससे छुटकारा पा सकता हूं ..?
+1

ऐसा लगता है जैसे आपको दो EventAggregators मिल रहे हैं; उनके लिए ऑब्जेक्ट आईडी बनाने के लिए डीबगर का उपयोग करें ताकि आप जांच सकें और हमें बता सकें। – GraemeF

+0

टिप के लिए धन्यवाद! क्या यह था, और वास्तव में यह वही EventAggregator है जिसका उपयोग मॉड्यूल में सदस्यता लेने और प्रकाशन के लिए किया जाता है। पहले शेल कन्स्ट्रक्टर में मिला। क्या "ऑब्जेक्ट आईडी बनाएं" था। मिला 1 #। फिर MyModule में ब्रेकपॉइंट मारा। प्रारंभ करें, और सत्यापित करें कि एग्रीगेटर में आईडी 1 # था। साथ ही प्रकाशित करने के लिए बटन को मारने पर भी मुझे लगता है कि इस्तेमाल किया गया एग्रीगेटर 1 # है। – stiank81

उत्तर

25

प्रिज्म इवेंट एग्रीगेटर घटनाओं से जुड़ने के लिए कमजोर संदर्भों का उपयोग करता है। यह ईवेंट हैंडलर से मेमोरी लीक को रोकने के लिए है।

एक बार एक मॉड्यूल प्रारंभकर्ता चलाया गया है, इसका निपटारा किया गया है, इसलिए घटना समाप्त होने से पहले आपके ईवेंट हैंडलर को नष्ट किया जा रहा है। आप सदस्यता के अधिभार का उपयोग करके ईवेंट हैंडलर को चारों ओर रखने के लिए प्रिज्म को बता सकते हैं।

evnt.Subscribe(MyModuleRequested, true); 

एक पैटर्न के रूप में, मैं एक अलग वर्ग में किसी भी घटना ग्राहकों रखा, और उस वर्ग फोन मॉड्यूल से विधि प्रारंभ करते हैं। इस तरह घटनाएं जीवित रहती हैं लेकिन मॉड्यूल अभी भी नष्ट होने पर अलग होती है।

+0

बिल्कुल सही! और आपका पैटर्न समझ में आता है - इसलिए मैं एक अलग वर्ग में एक न्यूनतम घटना हैंडलर डालूंगा। धन्यवाद..! – stiank81

+0

मुझे यह समस्या भी थी, प्रिज्म क्षेत्र में एक दृश्य जोड़ना मेरे मॉड्यूल को निपटाने से रोकता है, क्या मैं अपने क्षेत्र के पंजीकरण के साथ कुछ गलत कर रहा हूं? क्या आप अनुशंसित मॉड्यूल जीवनकाल और विचारों को पंजीकृत करने के बारे में किसी दस्तावेज़ के बारे में जानते हैं? – BenCr

2

तो, मुझे अभी एक सिद्धांत मिला है, लेकिन अभी इसका परीक्षण करने का कोई समय नहीं है .. कल करेंगे।

प्रश्न: मॉड्यूलसूची में मॉड्यूल जोड़ना उन्हें जीवित रखेगा? मुझे लगता है कि यह होगा। इसलिए - MyModule जीवित रहना चाहिए - और तब ईवेंट प्रकाशित होने पर ट्रिगर किया जाएगा।

protected override IModuleCatalog GetModuleCatalog() 
{ 
    var catalog = new ModuleCatalog(); 
    catalog.AddModule(typeof(MyModule)); 
    return catalog; 
} 

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

क्या यह इस मामले की तरह लगता है? यदि ऐसा है - मैंने अभी तक समाधान के बारे में नहीं सोचा है, इसलिए आप एक अलग उत्तर-थ्रेड में सुझाव देने के लिए स्वागत करते हैं ..

तो; वैसे भी मॉड्यूल कैटलॉग क्या है?शुरुआत के लिए बस एक सूची रखा गया और फिर फेंक दिया गया?

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