As you've discovered, the
DataTable
class is not thread-safe. If you try to add rows from multiple threads at the same time, the internal state will be corrupted.
The simple solution is to wrap the row addition in a
SyncLock
block:
SyncLock NwSData
If status = "Used" Then
NwSData.Rows.Add(My.Resources.Host, ipExport.ToString, hostName, macAddress, status, ipLong.ToString("D10"))
ElseIf status = "Free" Then
NwSData.Rows.Add(My.Resources.Free, ipExport.ToString, hostName, macAddress, status, ipLong.ToString("D10"))
Else
NwSData.Rows.Add(My.Resources.Unresolvable, ipExport.ToString, hostName, macAddress, status, ipLong.ToString("D10"))
End If
End SyncLock
SyncLock Statement - Visual Basic | Microsoft Docs[
^]
You will need to measure what performance impact that has on your code before deciding whether to explore a more complicated solution.
EDIT:
Based on the stack-trace of the exception, I suspect the grid doesn't like having the data source updated from a background thread. You may need to use
BeginInvoke
to update the table from the UI thread, which would remove the need for the
SyncLock
block. Try something like this:
If status = "Used" Then
BeginInvoke(Sub()
NwSData.Rows.Add(My.Resources.Host, ipExport.ToString, hostName, macAddress, status, ipLong.ToString("D10"))
End Sub)
ElseIf status = "Free" Then
BeginInvoke(Sub()
NwSData.Rows.Add(My.Resources.Free, ipExport.ToString, hostName, macAddress, status, ipLong.ToString("D10"))
End Sub)
Else
BeginInvoke(Sub()
NwSData.Rows.Add(My.Resources.Unresolvable, ipExport.ToString, hostName, macAddress, status, ipLong.ToString("D10"))
End Sub)
End If