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

时间:2015-10-19 12:57:47

标签: c# multithreading inotifypropertychanged

随着INotifyPropertyChanged的实现,我经常遇到典型的多线程异常:"调用线程无法访问此对象,因为另一个线程拥有它。"为了解决这个问题,我决定尝试实现一个线程安全的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));
           }
       }));                        
    }

我所注意到的是,存在显着的性能压力。除此之外,实施这种方法还有其他风险/顾虑吗?

修改

我正在使用WPF GUI技术。

1 个答案:

答案 0 :(得分:4)

您应首先检查您是否在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");