C# Winforms UI线程编组从后台线程更新的BusinessObject列表

C# Winforms UI线程编组从后台线程更新的BusinessObject列表,c#,.net,winforms,C#,.net,Winforms,首先,我知道有很多问题和解决方案来纠正从后台线程以外的线程进行的线程编组。我发现的所有问题和解决方案都集中在列表或业务对象本身引发 Windows窗体可以订阅更新,然后将更新正确地打包到主UI线程 在我的例子中,业务对象列表由一个单独层中的后台线程更新。我希望此列表绑定到主线程上的控件。我是否真的需要从业务对象列表向UI公开事件,以便正确编组更新?。我是否可以悄悄地更新业务对象列表并将这些更新传播到UI,而不必以某种方式向UI公开列表更改事件 编辑: 我的问题本质上是这样的:INotifyPro

首先,我知道有很多问题和解决方案来纠正从后台线程以外的线程进行的线程编组。我发现的所有问题和解决方案都集中在列表或业务对象本身引发 Windows窗体可以订阅更新,然后将更新正确地打包到主UI线程

在我的例子中,业务对象列表由一个单独层中的后台线程更新。我希望此列表绑定到主线程上的控件。我是否真的需要从业务对象列表向UI公开事件,以便正确编组更新?。我是否可以悄悄地更新业务对象列表并将这些更新传播到UI,而不必以某种方式向UI公开列表更改事件

编辑:


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

我在这里发布了一个选项(包括示例)-查找
ThreadedBindingList
(不要惊慌-大多数代码都在设置示例;list类非常小);这可能会有点帮助,但在我看来,您最好稍后再做UI更新


(不要错过线程下方的更新)

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

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

请参阅,如果对象实现绑定友好模式(例如
INotifyPropertyChanged
),并且将其中一个/多个对象绑定到UI,并且在幕后以某种方式更新对象,从而导致这些绑定友好事件中的任何一个都会出现在UI上,您的“对象已更改”通知正在访问UI代码,导致跨线程异常

更新:绕过引发违规事件的对象的一种方法是实现某种“STFU”对象级别变量,当从非UI线程更新对象状态时,该变量可以设置为true。然后,在“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);
      }
   }
}

ThreadedBindingList看起来真不错。我想我会试一下。谢谢Marc,我会看一看。Marc,你是建议我让UI来处理更新吗?请看下面我对Yoopegeek的评论。我说这是一个可能的选择。YMMV。但是,它确实会使这种类型的跨线程工作变得复杂…Marc,我刚刚测试了你的threadedbinding列表,效果很好,有一些错误处理,我想我可以使用它。谢谢。我知道这正是问题所在!我正在实现那些绑定友好的接口。但是如果我让UI处理我对业务对象所做的更新,我就破坏了封装。用户界面被拉入到处理所有权限都不知道的更新中。@Mule:“用户界面被拉入到处理所有权限都不知道的更新中。”:嗯,但这正是您首先实现绑定接口的原因。倾听这些事件是UI的职责。