views:

456

answers:

2

I have the following problem: Multithreaded WPF application, Model View Presenter Implementation. Presenters and Views that belong together are created on a separate thread and get a separate Dispatcher. Now someone calls from another thread a method on the Presenter. I am intercepting the call, and now begins the problem: if the call comes from the same thread as the presenter, i want to proceed with the call, else invoke the call on the Dispatcherthread, so that i don't need to care about UI calls. I have already read about the use of SynchronizationContext, but that doesnt seem to work for me because if the calling thread is no UI thread i can't compare the 2 contexts. Whats a possible, working and elegant solution ?

+3  A: 
if( presenterDispatcherObject.CheckAccess() )
   Doit();
else
  presenterDispatcherObject.BeginInvoke( DispatcherPriority.Normal, () => DoIt() );
jyoung
A: 

If you want the Dispatcher call to block (wait for return), I would use Invoke instead of BeginInvoke. This would mimic more of the behavior of actually calling the function directly. Invoke blocks calling thread until function is finshed (more like a Win32 SendMessage). BeginInvoke just posts and returns without waiting for function to return (like a Win32 PostMessage).

CheckAccess is slow. I would limit CheckAccess by keeping the calls less chatty on different threads.

public delegate bool MyFuncHandler(object arg);

bool ThreadedMyFunc(object arg)
{
    //...

    bool result;

    //...

    // use dispatcher passed in,  I would pass into the contructor of your class
    if (dispatcher.CheckAccess())
    {
        result = MyFunc(arg);
    }
    else
    {
        result = dispatcher.Invoke(new MyFuncHandler(MyFunc), arg);
    }

    return result;
}

bool MyFunc(object arg)
{
    //...
}
John Z