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
2008-12-04 15:23:28
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
2008-12-05 02:36:40