使用 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完成。
我有这样的命令:
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完成。