具有ObservesProperty的多线程

本文关键字:多线程 ObservesProperty 具有 | 更新日期: 2023-09-27 17:57:56

我有这样的命令:

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

当在非UI线程中设置IsProcessing时,似乎ObservesProperty会导致问题。它是bug还是按设计工作?

具有ObservesProperty的多线程

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

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

您应该:

  • 在启动线程之前/之后,从UI线程设置属性。使用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完成的线程。