2

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

sunder
  • 1,803
  • 4
  • 29
  • 50

4 Answers4

1

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.

Servy
  • 202,030
  • 26
  • 332
  • 449
1

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

Robin Rizvi
  • 5,113
  • 4
  • 27
  • 35
  • In this case his background task is periodically reporting progress, which the BGW supports, but that you haven't discussed here. That will add several more steps. – Servy Feb 06 '13 at 18:36
  • Background worker will not work here. Because it's never ending process. The core module will keep on running till application runs. – sunder Feb 07 '13 at 11:04
  • So use the ReportProgress method (2nd overload) (its does the same thing as Invoke) and can be used to send userobject to ui thread and make the ui thread update the ui and that is what you want. Note : BackgroundWorker is just an abstraction over low level threads so it can function even if its a never ending process and would end with the ending of the process – Robin Rizvi Feb 07 '13 at 12:12
0

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

Community
  • 1
  • 1
sircodesalot
  • 11,231
  • 8
  • 50
  • 83
0

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

sacha barber
  • 2,214
  • 1
  • 24
  • 37
  • Why build your own when you have the `Progress` class built into the framework to do this for you? – Servy Feb 06 '13 at 17:27
  • Yeah sorry I think I misread his intent. What I was suggesting is still very valid method of communicating between disconnected modules though. Say in different assemblies even. Its a power thing is Mediator pattern, but yeah sure for this, what you suggest is better idea – sacha barber Feb 08 '13 at 10:11