views:

149

answers:

2

I am trying to update a progress bar in my main form while a background task is running.

I am using the EventAggregator from the latest Patterns & Practices release route my application wide events.

I am firing an event from a class listens to BackgroundWorker events and than fires an event as such:

  1. Process on bw fires the BW method to report progress.
  2. BW fires it's reporting events.
  3. They get picked up by the SomeCommand class methods were set on the BW before it was launched.
  4. I publish Events from the EventAggregator

public void ProgressChanged (object sender, ProgressChangedEventArgs ea) { KnownProgressStatusChangedEvent evt = KernelKeeper.Kernel.Get().GetEvent(); evt.Publish(ea); }

My MainPresenter has subscribed to those events as such:

    KnownProgressStatusChangedEvent progressChanged = EventAggregator.GetEvent<KnownProgressStatusChangedEvent>();
    progressChanged.Subscribe(KnownProgressChanged,ThreadOption.UIThread);

If I don't set the ThreadOption.UIThread I get TargetInvokationException in the Program.cs with no stack trace. This way I get no exception and I can step in the EventAggregator.

When it is about to call the KnownProgressChanged method it tries to invoke it and checks for Application.Current != null. It is null and nothing is fired.

What am I doing wrong ? Please advise.

A: 

You have to specify ThreadOption.UIThread because you are dealing with a progress bar, the handler must be called from the ui thread to be able to draw the new progress state.

Howerver if you are working with WPF you have to handle it without ThreadOption.UIThread and dispatch the call yourself, you may take a look at the CompositeWpfEvent.

See Event Aggregator - Subscribing on the User Interface Thread

Frequently, subscribers will need to update user interface elements in response to events. In Windows Presentation Foundation (WPF), only a UI thread can update user interface elements. By default, the subscriber receives the event on the publisher's thread so if the publisher sends the event from the UI thread, the subscriber will be able to update the user interface.

However, if the publisher's thread is a background thread, the subscriber may be unable to directly update user interface elements. Instead, it would need to schedule the updates on the UI thread using the Windows Presentation Foundation's Dispatcher class. The CompositeWpfEvent provided with the Composite Application Library can assist by allowing the subscriber to automatically receive the event on the UI thread. The subscriber must indicate this during subscription, as shown in the following code.

...

Guillaume
That is indeed what I have done. In bullet 5) I have listed the code.Do I have to set it somewhere else ?
Tomas Pajonk
I Edited my answer to point out specificities of WPF.
Guillaume
A: 

TargetInvocationException was a red herring, which I caused by throwing a not implemented exception elsewhere in my code.

I am using WinForms and used the Subscribe with the ThreadOption.PublisherThread option and that works fine.

Tomas Pajonk