随着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技术。
答案 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");