INotifyPropertyChanged:线程安全 Dispatcher 实现的风险

INotifyPropertyChanged: Risks with thread-safe Dispatcher implementation

随着 INotifyPropertyChanged 的​​实现,我经常遇到典型的多线程异常:"The calling thread cannot access this object because a different thread owns it."为了解决这个问题,我决定尝试实现一个线程安全的 OnPropertyChanged 方法,如下所示:

    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        Application.Current.Dispatcher.Invoke(new Action(() =>
       {
           if (handler != null)
           {
               handler(this, new PropertyChangedEventArgs(name));
           }
       }));                        
    }

我注意到,存在显着的性能压力。除此之外,是否还有其他 risks/concerns 实施此方法?

编辑

我正在使用 WPF GUI 技术。

您应该首先检查您是否在 UI 线程上以避免不必要的调度:

Dispatcher dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
if (dispatcher != null) // already on UI thread, no dispatching needed
{
       if (handler != null)
       {
           handler(this, new PropertyChangedEventArgs(name));
       }
}
else
{
   Application.Current.Dispatcher.Invoke(new Action(() =>
   {
       if (handler != null)
       {
           handler(this, new PropertyChangedEventArgs(name));
       }
   }));
}

上面的代码片段可能需要更改,因为您没有指定使用了哪种 GUI 技术,但您明白了。

但是如果你问我,你应该一起选择不同的方法,在修改属性时进行调度:

Application.Current.Dispatcher.Invoke(new Action(() =>
    MyViewModel.MyProperty = "X");