May 21, 2014 at 8:15 PM
Edited May 21, 2014 at 10:46 PM
Code that was working with Prism 4.1 now throws an InvalidOperationException saying that the object (an instance of DelegateCommand) does not belong to the UI thread.
The following remark is found in the "What's New in Prism Library 5.0 for WPF" text :
DelegateCommand includes support for async handlers and has been moved to the Prism.Mvvm portable class library. DelegateCommand and CompositeCommand both use the WeakEventHandlerManager to raise the CanExecuteChanged event. The WeakEventHandlerManager must
be first constructed on the UI thread to properly acquire a reference to the UI thread’s SynchronizationContext.
Is seems clear that DelegateCommandBase has changed the way it handled the RaiseCanExecuteChanged calls, but it isn't clear to me what to do about it (events frequently reach our UI application on a different thread and should be able to trigger updates like
updating the CanExecute status of a Command).
The text above seems to be trying to hint at what I should do, but I need a bigger hint. WeakEventHandlerManager is a static class so 'constructing' it 'on the UI thread' isn't going to work.
I am afraid I don't completely understand the scenario where you are having problems. You mentioned that
are being published on a background thread, causing an exception when trying to update the
property. Is this correct?
It would be helpful if you could provide a small sample showing the issue you are describing, so we could have better understanding of the situation and give you better support by troubleshooting the solution.
I've got the exact same issue. Here's a stack trace:
System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
at System.Windows.Controls.Primitives.ButtonBase.OnCanExecuteChanged(Object sender, EventArgs e)
at System.Windows.Input.CanExecuteChangedEventManager.HandlerSink.OnCanExecuteChanged(Object sender, EventArgs e)
at Microsoft.Practices.Prism.Commands.WeakEventHandlerManager.CallHandler(Object sender, EventHandler eventHandler)
at Microsoft.Practices.Prism.Commands.WeakEventHandlerManager.CallWeakReferenceHandlers(Object sender, List`1 handlers)
I'm calling DelegateCommand.RaiseCanExecuteChanged() from non-UI threads. I expect this is a relatively common occurrence and shouldn't need further explanation. This used to work just fine in Prism 4.1. Now that the commands are async, there is some additional
marshalling happening and it's not happening correctly. The new DelegateCommandBase is not marshalling to the UI thread, I suspect because the WeakEventHandlerManager which is supposed to do the marshalling is not being constructed on the UI thread. And as
toolcontrol said, WeakEventHandlerManager is a static class so 'constructing' it 'on the UI thread' isn't going to work.
toolcontrol: Have you been able to resolve this in the meantime?