【问题标题】:Winforms cross-thread databinding using BindingList(Of T) in vb.net在 vb.net 中使用 BindingList(Of T) Winforms 跨线程数据绑定
【发布时间】:2014-08-11 17:15:09
【问题描述】:
  1. 我的主 GUI 表单 (lstDevices) 上有一个 ListBox。
  2. 它绑定到一个 BindingList(of Devices) [AvailableDevices],它是类 [NetworkManager] 的一个属性。
  3. 此 BindingList 在网络管理器类中更新(添加/删除),由与表单 UI 不同的线程触发。
  4. 每次更新它(BindingList)时都会引发跨线程错误,并且基于 UI 的列表框永远不会更新。

    表单伪代码:

    Dim WithEvents disc As New UPnPDeviceManager.NetworkManager

    lstDevices.DataSource = disc.AvailableDevices

    lstDevices.DisplayMember = "FriendlyName"

H-E-L-P

【问题讨论】:

  • BindingList 不是线程安全的。您只能在 UI 线程上触摸它。
  • 我可以使用什么来触发通知事件(线程安全)。我尝试了 list(of type) - 但这没有用..?

标签: vb.net multithreading winforms list data-binding


【解决方案1】:

您应该使用BeginInvoke() 对 UI 线程上的 BindingList 进行所有更改。

【讨论】:

    【解决方案2】:

    如果您修改BindingList 的代码在一个表单中,那么您可以使用该表单的InvokeBeginInvoke 方法来编组对UI 线程的调用并在那里修改BindingList。如果修改 BindingList 的代码在非 UI 类中,您的问题表明是这种情况,那么您应该在您的类中使用 SynchronizationContext 类来对列表进行线程安全的修改,例如

    Imports System.Threading
    
    Public Class SomeClass
    
        Private threadingContext As SynchronizationContext = SynchronizationContext.Current
    
        Private Sub DoSomething()
            Dim data As Object
    
            '...
    
            'Execute DoSomethingElse on the same thread that the current object was created on.
            Me.threadingContext.Post(AddressOf DoSomethingElse, data)
    
            '...
        End Sub
    
        Private Sub DoSomethingElse(data As Object)
            'Cast data parameter as appropriate type and use here.
        End Sub
    
    End Class
    

    只要您在 UI 线程上创建该类的实例,DoSomethingElse 将始终在 UI 线程上执行,而不管 DoSomething 在哪个线程上执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-07
      • 2010-10-02
      • 2013-03-02
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多