gpt4 book ai didi

c# - INotifyPropertyChanged 与线程

转载 作者:太空狗 更新时间:2023-10-29 20:49:51 25 4
gpt4 key购买 nike

我有一个

 BindingList<T>

绑定(bind)到数据 GridView 。我类的一个属性需要很长时间才能计算,所以我线程化了这个 Action 。计算完成后,我引发 OnPropertyChanged() 事件以通知网格该值已准备就绪。

至少,这是理论。但是由于 OnPropertyChanged 方法是从不同的线程调用的,所以我在网格的 OnRowPrePaint 方法中遇到了一些奇怪的异常。

谁能告诉我如何在主线程中执行 OnPropertyChanged 事件?我不能使用 Form.Invoke,因为类 MyClass 不知道它在 Winforms 应用程序中运行。

public class MyClass : INotifyPropertyChanged
{
public int FastMember {get;set;}

private int? slowMember;
public SlowMember
{
get
{
if (slowMember.HasValue)
return slowMember.Value;
else
{
Thread t = new Thread(getSlowMember);
t.Start();
return -1;
}

}
}

private void getSlowMember()
{
Thread.Sleep(1000);
slowMember = 5;
OnPropertyChanged("SlowMember");
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangingEventHandler eh = PropertyChanging;
if (eh != null)
{
eh(this, e);
}
}

}

最佳答案

人们有时会忘记事件处理程序是一个 MultiCastDelegate,因此,它拥有关于每个订阅者的所有信息,我们需要优雅地处理这种情况,而不会不必要地施加 Invoke+Synchronization 性能损失。多年来我一直在使用这样的代码:

using System.ComponentModel;
// ...

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
foreach (EventHandler h in handler.GetInvocationList())
{
var synch = h.Target as ISynchronizeInvoke;
if (synch != null && synch.InvokeRequired)
synch.Invoke(h, new object[] { this, e });
else
h(this, e);
}
}
}

它的作用很简单,但我记得当时我几乎绞尽脑汁试图找到最好的方法。

它首先“获取”本地属性上的事件处理程序以避免任何竞争条件。

如果处理程序不为空(至少存在一个订阅者),它会准备事件参数,然后遍历此多播委托(delegate)的调用列表。

调用列表具有 target 属性,它是事件的订阅者。如果此订阅者实现了 ISynchronizeInvoke(所有 UI 控件都实现了它),那么我们将检查它的 InvokeRequired 属性,确实我们只是通过委托(delegate)和参数调用它。以这种方式调用它会将调用同步到 UI 线程。

否则我们直接调用事件处理程序委托(delegate)。

关于c# - INotifyPropertyChanged 与线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1880151/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com