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 ?
-
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