Here is a code sample, you will need to place a ListBox called list_of_items onto the form, to reproduce the issue I’m having:
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
Problem is that rows do get added physically, so DataTable.Rows.Count increases, but visually nothing happens. I tried calling Refresh, resetting DataSource to Nothing and back – it does not help. If I switch this to single thread processing, rows get added just fine with the illustrated approach. What could be the issue?
I was playing around
Me.Invokeand found that if I add a dummy record synchronously usingInvoke, all records I added previously actually get added. Then I just need to remove this dummy record from aDataTable. If you have a better solution or a more elegant workaround, or you can explain why it works like this, please feel free to post it as an answer. Here is how the code looks now: