Search code examples
c#prismprism-5

C# delegate called twice?


I have created an output window where multiple events are subscribed to using Prism's EventAggregator. So far the constructor is handling two different events:

public OutputWindowView(IEventAggregator eventAggregator)
{
    eventAggregator.GetEvent<LoginStatusEvent>().Subscribe(trackLogin, true);
    eventAggregator.GetEvent<ConsoleMessageEvent>().Subscribe(trackMessage, true);

    this.InitializeComponent();
}

Both events target the same UI component via SetText method:

private void trackLogin(LoginStatus s)
{
    SetText("Connected: " + s.IsConnected.ToString());
}

private void trackMessage(string s)
{
    SetText(s);
}

I am trying to create a delegate to avoid thread errors.

private delegate void SetOutputText(string content);

private void SetText(string content)
{

    Trace.WriteLine("===== SetText =====");

    var text = content + Environment.NewLine;

    if (this.txtOutput.Dispatcher.CheckAccess() == false)
    {
        Trace.WriteLine("->CheckAccess > false");
        SetOutputText _output = new SetOutputText(SetText);
        this.Dispatcher.Invoke(_output, text);
    }
    else
    {
        Trace.WriteLine("->CheckAccess > true");
        this.txtOutput.Text += text;
    }

}

The output hover is:

===== SetText =====
->CheckAccess > false
===== SetText =====
->CheckAccess > true

I would expect the output to be:

===== SetText =====
->CheckAccess > false

OR

===== SetText =====
->CheckAccess > true

but it seems to be called twice.


Solution

  • You can subscribe on the UI thread by passing ThreadOption.UIThread like this

    eventAggregator.GetEvent<ConsoleMessageEvent>().Subscribe(trackMessage, ThreadOption.UIThread, true);
    

    or even simpler, bind to a property on your viewmodel and you're done, because INotifyPropertyChanged events are marshalled to the UI thread automatically.