sunder
sunder

Reputation: 1843

C# thread communication using events

I want to achieve something life below -

enter image description here

My application will start UI Module, from UI module I will initiate core module. Core module will keep on running on different thread. On specific action in core module, I want to raise and event which will be subscribed by UI module.

Basically, I want to send specific enum information to UI module.

Please suggest me a model for it. I am trying to achieve it.

Will both module run with any blocking in this model?

Thanks in advance

Upvotes: 2

Views: 3023

Answers (4)

Robin Rizvi
Robin Rizvi

Reputation: 5183

I would recommend using the BackgroundWorker Class

Checkout this tutorial http://www.dotnetperls.com/backgroundworker

Class reference http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Here how it goes in simple ways:

  1. Open your UI form (design view)
  2. Add a backgroundworker control on your UI form
  3. Open the properties pane and switch to events (lightning bolt icon)
  4. Double click on dowork and runworkercompleted events (this will generate event handlers)
  5. Go to the event handlers (in code)
  6. Now write your processing code in dowork handler and add the result you want to send to your ui module like so e.Result = your_enum (or any other Object);
  7. Next come to the runworkercompleted handler and typecast the RunWorkerCompletedEventArgs e (RunWorkerCompletedEventArgs object) to your enum (or object you returned from the dowork handler) and use it in UI as needed.
  8. Finally do not forget to initiate the backgroundworker : backgroundWorker1.RunWorkerAsync() from your UI mdoule

Remark: If you need to report progress periodically use the ReportProgress method of BackgroundWorker class. There are two overloads for this method: 1) http://msdn.microsoft.com/en-us/library/ka89zff4.aspx 2) http://msdn.microsoft.com/en-us/library/a3zbdb1t.aspx

The first one allows to report only the progress percentage and the second one you can use to pass in any object also if you will

Upvotes: 1

sacha barber
sacha barber

Reputation: 2333

Sounds like a classic use of the Mediator pattern to me. The Mediator allows disconnected components to talk to each other.

I just happen to have a copy of this in my own MVVM framework, which you can grab from here :

http://cinch.codeplex.com/SourceControl/changeset/view/70832#796984

Also grab this

http://cinch.codeplex.com/SourceControl/changeset/view/70832#797008

My implementation allows you to do it using WeakReference so no strong references are held. Its also allows subscribers to hook up methods to listen to certain events using attributes, and publishers to broadcast a new messaage of T.

Publisher/Subscriber simply register with Mediator

//done by both subscriber and publisher
Mediator.Instance.Register(this);


//Subscriber
[MediatorMessageSinkAttribute("DoBackgroundCheck")]
void OnBackgroundCheck(string someValue) { ... }


//publisher might typically do this
mediator.NotifyColleagues("DoBackgroundCheck", "Nice message");

You may need to use your own SynchronizationContext when subscriber gets message (WPF / Winforms have pre built ones of these) to dispatch call to correct thread.

I also allow for synchronise/aysynchronise calls

Upvotes: 0

Servy
Servy

Reputation: 203802

You can use the Progress class with the IProgress interface to do exactly this.

  1. In your UI context create a Progress object with a generic argument of whatever data you need to pass.

  2. Subscribe to it's event to do whatever you want to do when the background task updates you.

  3. Have the background task accept an object of type IProgress (which Progress implements) and have it periodically Report with the relevant data.

The ProgressChanged event will be fired whenever Report is called, and the Progress object will capture the current synchronization context of where it was created, which is a fancy way of saying that the event will be fired in the UI thread.

Upvotes: 1

sircodesalot
sircodesalot

Reputation: 11439

This should be pretty easy to do with either the System.Threading.Thread or BackgroundWorker or Task class. You can use either of those to run code on another thread.

When you need to notify the UI, just raise an event. To build events, take a look here:

How can I make my own event in C#?

Then you just need to make sure to call Invoke to make sure that you execute the final UI update code on the correct thread. For that, take a look at this:

Thread Control.Invoke

Upvotes: 0

Related Questions