Messaging - Is Unregister required?

Topics: Questions
Sep 9, 2012 at 8:35 PM

Do we have to unregister message listener on releasing parent class. 

In the deconstructor?

What will happen if we create and release many instances of a class with message recipient without Unregistering?

 

 

Coordinator
Sep 10, 2012 at 7:54 AM

No, everything is managed by weak references so no memory leaks can occur. You only have to unregister when you are no longer interested in a message.

You might also be interested in messaging with attributes, which handles subscription/unsubscription automatically for you.

Sep 10, 2012 at 11:08 AM
Edited Sep 10, 2012 at 11:10 AM

Thank you.

As I understand, the message and the tag are object, so don't have to stick to strings only.

I'm developing an application with tabbed GUI. User can open separate tab pages (1 - 20) and to start heavy resource consuming process in each tab. The math will be in separate threads, but results will be updated via Messages. Calculated data can vary from 10 to 300 mega bites. Updates will be send on various intervals from 1 sec to 1 minute. Also a common monitoring interface will listen all threads and will present a summery of the calculations. 

I'm afraid that different threads will lock each other if I use a common MessageMediator (or not?).  Can I instantiate a separate mediator for each thread for internal communication?

I made a simple multithreading test with message progress report and it works fine for now.

 

using System;
using System.Threading;
using System.Windows.Forms;
using Catel.Messaging;

namespace TestMessagingMultiThread
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            IMessageMediator messageMediator = MessageMediator.Default;
            messageMediator.Register<string>(this, OnMessage);

            for (int i = 0; i < 20; i++)
            {
                var thread = new Thread(StartHeavyProcess) {Name = "Thread " + (i + 1)};
                thread.Start();
            }
        }

        private void StartHeavyProcess()
        {
            IMessageMediator messageMediator = MessageMediator.Default;
            for (int i = 0; i < 20; i++)
            {
                Thread.Sleep(200);
                messageMediator.SendMessage(string.Format("{0} , iteration: {1}\r\n", Thread.CurrentThread.Name, (i + 1)));
            }
        }

        public void OnMessage(object message)
        {
            if (textBox1.InvokeRequired)
                textBox1.BeginInvoke(new OnMessageDelegate(OnMessage), new[] { message });
            else
                textBox1.AppendText(message.ToString());
        }

        private delegate void OnMessageDelegate(object message);
    }
}
Coordinator
Sep 10, 2012 at 12:46 PM

You don't have to be afraid of deadlocks. Just use DispatcherService.BeginInvoke() and the message will be dispatched immediately and added to the UI update thread queue. 

You might be interested in Orchestra, a framework using WPF, Catel, Prism, AvalonDock and FluentRibbon. This way, you don't have to worry about the actual framework with tabs, but you can start writing modules immediately. Keep in mind that it is in alpa/beta stage, but it is already usable and the first beta package is published via nuget.