Click here to Skip to main content
15,890,282 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I was wondering about how to marshal callbacks from within the worker thread, when you don't know the thread that created the object being called into. Using ISynchronizeInvoke interface was simple enough - I used code like:
C#
class MyMultithreadClass {
  public event EventHandler MarshalledEvent;

  private void FireMarshalledEvent() {
    if (MarshalledEvent != null) {
      foreach (Delegate d in MarshalledEvent.GetInvocationList()) {
        if (d.Target is ISynchronizeInvoke && ((ISynchronizeInvoke)d.Target).InvokeRequired) {
          ((ISynchronizeInvoke)d.Target).Invoke(d, new object[] { this, EventArgs.Empty });
        }
        else
          ((EventHandler)d)(this, EventArgs.Empty);
      }
    }
  }
}


I was wondering how to do this type of thing for a WPF based application. I understand the use of the Dispatcher object, but to get the Dispatcher for a particular thread, you need to know the thread the object was created on.
The reason for this is that the multithreaded class is going into a library, and it would be nice for the caller not to have to know if their call is to be run on a worker thread or not, and not to have to put marshalling code into every event handler.
Posted

1 solution

I have found the solution. Apparently, any object that requires a Dispatcher inherits from the DependencyObject class. This allows for the same pattern as above, only using DependencyObject instead of ISynchronizeInvoke, and CheckAccess() method instead of InvokeRequired property.
C#
if (MarshalledEvent != null) {
  foreach (Delegate d in MarshalledEvent.GetInvocationList()) {
    if (d.Target is DependencyObject && ((DependencyObject)d.Target).Dispatcher.CheckAccess() == false)
      ((DependencyObject)d.Target).Dispatcher.Invoke(d, new object[] { this, EventArgs.Empty });
    else
      d.DynamicInvoke(this, EventArgs.Empty);
  }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900