Reputation: 34489
Within a class library I'm writing I have a method allowing the library to go and do some stuff on a different thread which does something like:
public void DoStuffAsync(AP p)
{
this.Running = true;
this.Cancel = false;
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(DoStuff);
Thread procThread = new Thread(threadStart);
procThread.Start(p);
}
I also have a number of events declared on the interface that the developer can hook into, such as StatusUpdate and ProgressUpdate. I'm currently writing a little test app (in WPF presently although I expect the same behaviour in WinForms) that calls DoStuffAsync() and then updates a progress bar and label.
Unfortunately 1st pass I got an error, the usual thread not being the one which owns the controls. What I'd like to do is remove the need for the user to call Invoke() within the UI side, and for them to simply subscribe to the events and have them work.
So the question, is there a way I can do this is my code when dealing with the event handlers? Currently trigger like so:
public void UpdateProgress(object sender, ProgressEventArgs e)
{
if (handler != null)
{
handler(sender, e);
}
}
Upvotes: 4
Views: 555
Reputation: 14726
Use the AsyncOperationManager instead.
It will do the invoke for you. (internally it uses the SynchronizationContext as nobugz describes)
Upvotes: 3
Reputation: 941257
You will need a reference to the client's Dispatcher object so you can call Dispatcher.Invoke or Dispatcher.BeginInvoke to marshal the call to the client's UI thread. Do so by letting the client give you the reference you'll need either through the constructor or with a property.
Another way to do it is to store a reference to SynchronizationContext.Current in your class constructor. Use its Send or Post method. That however requires the client to have WPF initialized properly (Application.Run must have been called) and construct your class object from its UI thread.
Upvotes: 3