以下是代码示例,您需要在表单上放置一个名为ListBox
的{{1}},以重现我遇到的问题:
list_of_items
问题是行会在物理上添加,因此Imports System.Threading.Tasks
Public Class Form1
Dim _dt As DataTable
Private Sub Form1_Load() Handles MyBase.Load
_dt = New DataTable
With _dt.Columns
.Add("key")
.Add("value")
End With
With list_of_items
.ValueMember = "key"
.DisplayMember = "value"
.DataSource = _dt
End With
Dim addItemsTask As New Task(AddressOf AddThreeItems)
addItemsTask.Start() 'does not add anything when done
'AddThreeItems() #doing this instead works!
End Sub
Private Sub AddThreeItems()
Threading.Thread.Sleep(2000)
With _dt.Rows
.Add({"1", "One"})
.Add({"2", "Two"})
.Add({"3", "Three"})
End With
Me.Invoke(Sub() Me.Text = "Separate thread is done")
End Sub
End Class
会增加,但在视觉上没有任何反应。我尝试调用DataTable.Rows.Count
,将Refresh
重置为DataSource
然后重新启动 - 它没有帮助。如果我将其切换为单线程处理,则使用图示的方法可以很好地添加行。可能是什么问题?
答案 0 :(得分:1)
重新分配数据源
Me.Invoke(
Sub()
list_of_items.DataSource = Nothing
list_of_items.DataSource = _dt
Me.Text = "Separate thread is done"
End Sub
)
答案 1 :(得分:1)
我正在玩Me.Invoke
并发现如果我使用Invoke
同步添加虚拟记录,我之前添加的所有记录实际上都会被添加。然后我只需要从DataTable
中删除这个虚拟记录。如果您有更好的解决方案或更优雅的解决方法,或者您可以解释它为何如此工作,请随时将其作为答案发布。以下是代码现在的样子:
Private Sub AddThreeItems()
Threading.Thread.Sleep(2000)
With _dt.Rows
.Add({"1", "One"})
.Add({"2", "Two"})
.Add({"3", "Three"})
End With
Me.Invoke(Sub()
_dt.Rows.Add()
_dt.Rows.RemoveAt(_dt.Rows.Count - 1)
Me.Text = "Separate thread is done"
End Sub)
End Sub