Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF和NotifyPropertyChanged来自不同的线程_C#_Wpf_Multithreading - Fatal编程技术网

C# WPF和NotifyPropertyChanged来自不同的线程

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

我对WPF很有经验,但有一件事困扰着我。我正在使用ReactiveUI引发INotifyPropertyChanged事件。我有两个类似的地方:

 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
    事件,通常来自视图模型绑定
我确信WPF没有自动调用第一个列表有一个很好的理由,但我不知道它可能是什么

我对处理服务事件的建议如下:

  • 维护对从UI线程捕获的
    SynchronizationContext
    的引用(可能在这里对您最有用)
  • 使用中介服务调用UI线程上的应用程序事件处理程序

  • 只有在实际尝试从与UI线程不同的线程修改UI元素时,才会出现异常。这是在第二个地方发生的吗?我确实在两个地方修改了它们。当分配给UiModel时,我调用INotifyPropertyChanged,它会更新UIHanks mate,这很有意义!这是否有文档记录?还值得注意的是,自动封送仅由一些MVVM框架完成。WPF有,我相信Xamarin。WP没有,我也不知道UAP。