The example below uses the DelegateCommand from Prism 6.1, but I've produced the same issue with 5.0.
Using the following view-model (view omitted, just consists of 2 buttons):
public class MainWindowViewModel
{
public DelegateCommand TestCommand { get; set; }
public DelegateCommand ActionCommand { get; set; }
public MainWindowViewModel()
{
TestCommand = new DelegateCommand(()=> TestCommand.RaiseCanExecuteChanged());
ActionCommand = new DelegateCommand(() =>
{
Task.Run(() =>
{
Thread.Sleep(1000);
TestCommand.RaiseCanExecuteChanged();
});
});
}
}
If the ActiveCommand is called first, then this exception occurs:
An exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll but was not handled in user code
Additional information: The calling thread cannot access this object because a different thread owns it.
This is, as far as I can tell, the standard "you're not allowed to talk to Wpf controls if you're not on the UI thread" exception. This seems at odds with the method summary:
Raises Prism.Commands.DelegateCommandBase.CanExecuteChanged on the UI thread so every command invoker can requery to check if the command can execute.
Also, I've had no problem calling this method from non-UI threads in the past.
Weirder still, if the TestCommand is raised first, then the ActionCommand starts working fine. I've checked and the code inside the Task.Run block is running on a non-UI thread in all cases.
Unfortunately, I can't use this as a work around in my real code - I've tried having the UI thread call a RaiseCanExecuteChanged before a worker thread does it, and it doesn't help.
Is there any reason for RaiseCanExecuteChanged to act this way? Any fix or workaround?