سؤال

أنا أعمل على تنفيذ تجميع الأحداث مع المنشور. لديّ عدد قليل من الوحدات ، وأريد أن يشترك كل منها في الأحداث التي تخبرهم عند طلبها. بدأت في القيام بمثال واضح مع كل من الاشتراك والناشر في القشرة. لا توجد مشاكل هناك. حاليا؛ عندما أقوم بنقل المشتركين إلى وحداتاتي ، لا يتم تشغيلها. الأمر الأكثر غرابة هو أنه نجح بالفعل عدة مرات - وكل ذلك كنت معلقًا في نقطة توقف. لذلك يبدو لي أن تكون بعض حالة السباق ، لكنني لا أفهم السبب.

افتراض: لست بحاجة إلى إعداد ieventaggregator في أي مكان - على سبيل المثال التسجيل في حاوية IOC؟ هذا مدمج في المنشور بحيث ليس لدي سوى حالة واحدة من مجمع الأحداث ، أليس كذلك؟

لذا ، فإن السؤال هو في الأساس كيف/أين/عندما يجب أن أقوم بإعداد المشتركين. هل هناك ترتيب محدد على الأشياء وما إلى ذلك؟ في المثال المبسط ، لدي وحدة واحدة 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);
}

ملحوظات:

  • لقد تحقق من نشر الحدث. إن إضافة مشترك في Shell أيضًا سيجعل هذا المشترك يتلقى الحدث.
  • ثانية؛ لم يتم تشغيل المشترك في MyModule. ومع ذلك ، فقد كان - بشكل غريب - في مناسبات قليلة.
  • لا أستخدم المدخلات في الحدث. يبدو أنك بحاجة إلى الحصول على بعض المدخلات ، لذلك ذهبت للتو مع منطقة وهمية. هل يمكنني التخلص من هذا ..؟
هل كانت مفيدة؟

المحلول

يستخدم مجمع الأحداث Prism إشارات ضعيفة لربط الأحداث. هذا هو منع تسرب الذاكرة من معالجات الأحداث.

بمجرد تشغيل مُهيئ الوحدة النمطية ، يتم التخلص منه ، لذلك يتم تدمير معالج الحدث الخاص بك قبل إطلاق الحدث. يمكنك إخبار PRISM بالحفاظ على معالج الحدث حول استخدام حمولة زائدة من الاشتراك.

evnt.Subscribe(MyModuleRequested, true);

كنمط ، أميل إلى وضع أي مشتركين في فئة منفصلة ، واستدعاء تلك الفئة من طريقة تهيئة الوحدات النمطية. وبهذه الطريقة ، تبقى الأحداث على قيد الحياة ولكنها منفصلة بينما لا تزال الوحدة دمرت.

نصائح أخرى

لذلك ، لقد حصلت على نظرية ، لكن لا وقت لاختبارها الآن .. سأفعل غدًا.

سؤال: هل ستؤدي إضافة وحدات إلى ModuleCatalogue إلى إبقائها على قيد الحياة؟ لقد افترضت ذلك. وبالتالي - يجب أن تبقى mymodule على قيد الحياة - ثم سيتم تشغيلها عند نشر الحدث.

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

ومع ذلك ، إذا لم يحافظ هذا على الوحدة النمطية ، فمن الواضح أنه سيواجه صعوبة في الرد على الحدث. تموت الكائن النمطية ، لكنه لم يشرع الاشتراك - وبالتالي سأرى المشترك في قائمة Eventaggregator ، لكن المشترك لم يعد موجودًا. ايضا؛ ذكرت أنني في الواقع يعمل في بعض الأحيان - وهذا هو الحال إذا لم يكن لدى جامع القمامة وقت لإخراج القمامة قبل أن يتم تشغيل الحدث.

هل هذا يبدو مثل الحالة؟ إذا كان الأمر كذلك - لم أفكر في حل حتى الآن ، لذا فأنت مرحبًا بك في اقتراح واحد في رد فعل مختلف ..

لذا؛ ما هو MODULECATALOGE على أي حال؟ مجرد قائمة محفوظة للتهيئة ثم ألقيت بعيدا؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top