使用 ObservesProperty 的多线程

Multi threading with ObservesProperty

我有这样的命令:

CancelCommand = new DelegateCommand(Cancel, () => IsProcessing).ObservesProperty(() => IsProcessing);

在我调用的其他方法中

Task.Factory.StartNew(() =>
            {
                IsProcessing = true; // Stop here
                IsProcessing = false;
            });

IsProcessing 设置为 true 时,执行以某种方式停止。但是当我改成

Application.Current.Dispatcher.Invoke(() => IsProcessing = true);
IsProcessing = false; // Hit this line then stop again
int i = 0; // Never reach here

IsProcessing 设置在非 UI 线程中时,看起来 ObservesProperty 会导致问题。是错误还是按设计工作?

这个问题不是 Prism 独有的。所有 Prism 都会连接到您指定的 属性 的 INotifyPropertyChanged 并调用 CanExecuteChanged 事件。

事件 ICommand.CanExecuteChanged 可能会导致 UI 元素发生变化(例如改变按钮的 IsEnabled 属性 的值)- 因此必须从UI 线程。与绑定引擎不同,它不会自动执行此操作。

您应该:

  • 设置 属性 从 UI 线程 before/after 开始你的线程。使用 async/await 会很容易:

    async Task DoStuff() // start this method from the UI thread
    {
        IsProcessing = true;
        try
        {
            await Task.Run(() => { ... });
        }
        finally
        {
            IsProcessing = false;
        }
    }
    
  • 使用Dispatcher.InvokeAsync不要使用Invoke - 那只是在浪费线程等待UI完成。