Prism 5 DelegateCommandBase.RaiseCanExecuteChanged throws InvalidOperationException

Topics: Prism v4 - WPF 4
May 21, 2014 at 9:15 PM
Edited May 21, 2014 at 11: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.
May 23, 2014 at 7:35 PM
Hello,
I am afraid I don't completely understand the scenario where you are having problems. You mentioned that Events are being published on a background thread, causing an exception when trying to update the Command's CanExecute 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.

Regards.
Gabriel Ostrowsky.
https://blogs.southworks.net/gostrowsky
Sep 9, 2014 at 12:20 AM
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.Threading.Dispatcher.VerifyAccess()
at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
at System.Windows.Controls.Primitives.ButtonBase.get_Command()
at System.Windows.Controls.Primitives.ButtonBase.UpdateCanExecute()
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)
at Microsoft.Practices.Prism.Commands.DelegateCommandBase.OnCanExecuteChanged()

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.

Any ideas?

toolcontrol: Have you been able to resolve this in the meantime?