C# WPF和NotifyPropertyChanged来自不同的线程
我对WPF很有经验,但有一件事困扰着我。我正在使用ReactiveUI引发INotifyPropertyChanged事件。我有两个类似的地方:C# WPF和NotifyPropertyChanged来自不同的线程,c#,wpf,multithreading,C#,Wpf,Multithreading,我对WPF很有经验,但有一件事困扰着我。我正在使用ReactiveUI引发INotifyPropertyChanged事件。我有两个类似的地方: public UiModel UiModel { get { return _uiModel; } set { this.RaiseAndSetIfChanged(ref _uiModel, value); } } public
public UiModel UiModel
{
get { return _uiModel; }
set { this.RaiseAndSetIfChanged(ref _uiModel, value); }
}
public void Run()
{
UiModel = GetUIModel();
}
其中Run()
的调用方式如下wait Task.Run(()=>Run())
和UiModel
绑定在XAML
中。
所以基本上应该发生什么->如果在不同的线程上调用Run()
函数,它应该抛出一个跨线程异常,不是吗?代码中有两个地方,一个地方总是抛出异常,另一个地方从不抛出异常。我已经比较了线程ID,在这两个地方,Run()
不是在UI线程上运行的。为什么会这样?
在不抛出异常的地方,我将其绑定到UserControl中的Dependency属性,在第二个地方,我使用普通绑定将其绑定
引发异常:{“调用线程无法访问此对象,因为其他线程拥有它。”}
看起来我已经找到了这个特定情况的答案。UiModel及其绑定不会引发异常,但UiModel也用于反应UI验证。如果我不从UI更新它,它将尝试从导致该异常的不同线程更新CanExecuteChanged。尽管如此,我的问题仍然是一样的——为什么我可以从不同的线程更新UI而不出现跨线程异常?我在ReactiveUI PropertyChanged调用中看不到dispatcher调用。这方面存在一些令人讨厌的不一致。下面列出了可以从工作线程执行和不能从工作线程执行的操作 引发跨线程异常:
- 修改控件上的
从属属性
- 引发
事件ICommand.CanExecuteChanged
- 引发
事件,通常来自INotifyCollectionChanged.CollectionChanged
ObservableCollection的实例
- 引发
事件,通常来自视图模型绑定INotifyPropertyChanged.PropertyChanged
SynchronizationContext
的引用(可能在这里对您最有用)只有在实际尝试从与UI线程不同的线程修改UI元素时,才会出现异常。这是在第二个地方发生的吗?我确实在两个地方修改了它们。当分配给UiModel时,我调用INotifyPropertyChanged,它会更新UIHanks mate,这很有意义!这是否有文档记录?还值得注意的是,自动封送仅由一些MVVM框架完成。WPF有,我相信Xamarin。WP没有,我也不知道UAP。