c# - 从不同线程 vb.net 更新 BindingList(of T)

标签 c# vb.net multithreading bindinglist

几天前我一直在从其他线程寻找 BindingList Invoke,但无法在 vb.net 中获得合适的解决方案,其中大部分是在 C# 中,但我发现很难理解。 因此我创建了一个小型应用程序,它有 2 个窗体(Form1 和 Form2)和一个类,Form1 将作为主 UI 线程,而 Form2 将在不同的线程上运行。

Form1 有一个 DataGrindView 绑定(bind)到共享的 BindingList(of T) 和一个 Button,一旦单击 Button,Form2 将在不同的线程上加载。

这是 Form1 代码:

Imports System.ComponentModel
Imports System.Threading
Public Class Form1
    Public Shared ListOfNames As BindingList(Of Names) = New BindingList(Of Names)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.DataSource = ListOfNames
        DataGridView1.Columns("FullName").DataPropertyName = "FullName"
    End Sub

    Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
        Dim thread As Threading.Thread = New Threading.Thread(AddressOf loadQuoteForm)
        thread.SetApartmentState((ApartmentState.STA))
        thread.Start()
    End Sub

    Private Sub loadQuoteForm()
        Dim SecondForm As Form2 = New Form2
        Application.Run(SecondForm)
    End Sub
End Class

Form2 只有一个按钮,点击后会创建一个 Names 类实例,更改它的一个属性并尝试添加到 Form1.BindingList(of T)。

这是 Form2 代码:

Public Class Form2
    Private Sub btnTestFromDiffTread_Click(sender As Object, e As EventArgs) Handles btnTestFromDiffTread.Click
        Try
            Dim myName As Names = New Names
            myName.FullName = "John Peter"
            Form1.ListOfNames.Add(myName)
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub
End Class


Imports System.ComponentModel
Public Class Names
    Implements System.ComponentModel.INotifyPropertyChanged
    Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    Private _fullName As String
    Public Property FullName() As String
        Get
            Return _fullName
        End Get
        Set(ByVal value As String)
            _fullName = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("FullName"))
        End Set
    End Property
End Class

但是您可能已经猜到,一旦单击 Form2 上的按钮就会抛出异常: enter image description here .

任何人都可以建议我应该在哪里调用或委托(delegate),非常感谢示例 VB.net

最佳答案

这是导致问题的 DataGridView 的更新。

从您的评论中我可以看出这是因为 DataGridView 绑定(bind)到 DataGridView 的数据源,因此如果您在单独的线程上执行此操作,则更新此列表将导致跨线程操作。

一个解决方案是不公开 ListOfNames 并使用新方法允许添加到此列表:

Private Shared ListOfNames As BindingList(Of Names) = New BindingList(Of Names)

Public Sub AddNameToList(newNames As Names)
    DataGridView1.BeginInvoke(Sub() ListOfNames.Add(newNames))
End Sub

关于c# - 从不同线程 vb.net 更新 BindingList(of T),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38398101/

相关文章:

c# - EPPlus Excel 文件。显示对角线单元格的正确输出

arrays - 如何比较两个字符串数组?

vb.net - 如何在 VB.NET 中进行按位与运算?

java - 最终网页后运行java程序

java - 创建单例实例的工厂方法

multithreading - 线程、Coro、Anyevent 混淆

c# - 是否可以将 List 绑定(bind)到 WinForms 中的 ListView?

c# - 如何检测我的页面是否是回发的结果

c# - 在 ASP.Net 网站项目中混合使用 VB.Net 和 C# 代码?

c# - 正则表达式允许所有字符,长度应为 1-50 个字符