Friday, March 4, 2011

How to delegate a method call to another thread ?

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 ?

From stackoverflow
  • if( presenterDispatcherObject.CheckAccess() )
       Doit();
    else
      presenterDispatcherObject.BeginInvoke( DispatcherPriority.Normal, () => DoIt() );
    
  • 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)
    {
        //...
    }
    

0 comments:

Post a Comment