2009-07-02 59 views
3

首先,我知道有很多问题和解决方案来纠正线程编组线程而不是后台线程。我发现的所有问题和解决方案都侧重于列表或业务对象自身引发Windows窗体可以订阅的事件,然后将更新正确编组到主UI线程的情况。Winforms UI线程编组Business Objects列表正在从后台线程更新

在我的情况下,业务对象列表正在由单独层中的后台线程更新。我希望这个列表绑定到主线程上的一个控件。我是否真的需要从业务对象列表中向用户界面公开事件,以便可以正确编组更新?我是否可以不静静地更新业务对象列表,并将这些更新传播到UI,而无需以某种方式将列表更改的事件暴露给UI?

编辑:

我的问题本质上是这样的:INotifyProperty改变被触发的属性已经改变了。绑定到实现此接口的对象的控件将尝试更新,如果引发事件触发的线程不是UI线程,则说明存在问题。所以我们需要通知我们想要更新的UI线程,以便可以以线程安全的方式处理更新,这意味着后台线程更新对象不能简单地执行它的业务,它必须要求权限更新对象或者要求UI代表它对对象进行更改。这就是我将UI拉入句柄对象更新的意思。

回答

1

我在这里this old usenet post发布了一个选项(包括示例) - 寻找ThreadedBindingList(不要惊慌 - 大部分代码是建立例子; list类是非常小的);它可能有点帮助,但IMO你可能会做的更好,以简单地做一个UI稍后更新...

(不要错过更新低的线程)

+0

ThreadedBindingList看起来非常好。我想我会试一试。 – 2009-07-02 21:10:59

+0

谢谢马克我会看看。 – AndyMM 2009-07-02 21:22:40

0

我的经验是,如果您将业务对象绑定到UI,对这些对象所做的任何更改都必须隐式地在UI线程上执行,否则您将获得跨线程异常。

当这些对象被绑定到UI时,从非UI线程更改对象是个坏消息。

看,如果你是对象实现结合型模式(如INotifyPropertyChanged例如,),并绑定一个/多个这些对象的UI,和你身后的幕后的方式更新您的对象,导致任何这些绑定友好事件陷入用户界面,你的'对象已经改变'通知正在使它成为UI代码的方式,从而导致跨线程异常。

更新:一种方法来解决你的对象提高了违规事件是执行某种可能被设置为true“STFU”对象级别的变量正在作出更新时从非物体状态-UI线程。然后,在您的“OnRaiseMyEvent(...)”方法中,您可以检查STFU变量的状态 - 如果为true,则STFU,否则,引发该事件。

更新#2:啊,用更新的问题,这是我在这种情况下所做的:传递一个ISynchronizeInvoke到业务对象的构造函数。然后,业务对象可以处理是否需要将事件提升编组到UI线程:

public class MyObject { 
    private ISynchronizeInvoke _Invoker; 

    public MyObject(ISynchronizeInvoke invoker) { 
     _Invoker = invoker; 
    } 

    private void OnPropertyChanged(string propertyName) { 
     PropertyChangedEventHandler handlers = this.PropertyChanged; 
     if (handlers != null) { 
     if (_Invoker.InvokeRequired) { 
     _Invoker.Invoke(handlers, new PropertyChangedEventArgs(propertyName)); 
     } else { 
     handlers(new PropertyChangedEventArgs(propertyName); 
     } 
    } 
}