views:

92

answers:

4

Hello,

I am developing an application that is split into multiple .NET assemblies (one main executable and a set of class libraries). Currently, I am using a WPF GUI, but I need to maintain the flexibility to possibly switch to another GUI framework at a later time.

Here is my problem: one of the class libraries performs some work on a separate thread, and raises an event when that thread is complete. I quickly discovered that my WPF GUI got upset when I tried to modify its components from this event handler, so I implemented an "event queue" that dispatches events on the main thread using a System.Windows.Threading.DispatcherTimer. This did the job; however, I was horrified to discover that this DispatcherTimer only works within the context of a WPF application!

I am trying to hide all the ugly details of multithreading within this class library, which may eventually be used in conjunction with a non-WPF GUI. The idea is, the consuming application should be able to update its GUI from within the event handlers. So, my question is, is there a standard method (independent of any particular GUI framework) for raising events on a different thread??

Any help would be appreciated. Thanks.

+1  A: 

You need to use ISyncronizeInvoke. This interface allows you to check if you are on the right thread, and if not, Invoke a method on the correct thread. I haven't done this in WPF, but I assume it is implemented there as well as Windows Forms.

davisoa
+1  A: 

Hi,

Typically you would just marshal the event data to the main thread by reinvoking the event handler from the main thread. One method is shown below.

private void DispalyMessage(byte[] bytes)
{
  if (this.InvokeRequired)
  {
    lock (_lock)
    {
      EventHandler d = new EventHandler(DispalyMessage);
      this.Invoke(d, new object[] { bytes });
      return;
    }
  }
  else
  {
    //do something with the data
  }
}

Enjoy!

Doug
A: 

You could use SynchronizationContext (which is what BackgroundWorker does, I believe) - or you could just warn your clients that the events will be raised on a background thread, and that they should perform whatever marshalling they need to (as other APIs like FileSystemWatcher do.)

Jon Skeet
A: 

Instead of events from the class library, use a callback method that your GUI code provides. Although the callback will be invoked on the library's thread, your GUI code can decide what's the best way to handle it. This should simplify switching to a different GUI.

ebpower