我正在尝试创建一个多线程程序来轮询机器以获取数据,但我似乎无法让它正常工作。下面的代码正在运行,并且正在创建 4 个线程,但代码流似乎是串行发生的,并且在主 UI 线程上发生。
我想要实现的是数据网格的每一行同时更新而不锁定 UI。
下面是我所拥有的内容的简化版本,但它可以证明问题。对于信息,“testclass”是用作机器实例的类,每个类元素代表机器的属性。
希望我已经提供了足够的信息来解释这个问题。提前致谢。
PS我应该不需要刷新表格吗?
Imports System.Threading
Public Class TestForm
Public threadcount As Integer
Public Delegate Sub testclassDelegate(test As Object)
Private Class testclass
Public index As Integer
Public TestVal1 As Integer = 100
Public TestVal2 As Integer = 200
Public TestVal3 As Integer = 300
Public TestVal4 As Integer = 400
Public TestVal5 As Integer = 500
Public TestVal6 As Integer = 600
Public testDel As testclassDelegate
End Class
Private Sub TestForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i As Integer = 0 To 3
DataGridView1.Rows.Add()
DataGridView1.Rows(i).Cells(0).Value = i + 1
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i As Integer = 0 To 3
DataGridView1.Rows(i).Cells(1).Value = ""
DataGridView1.Rows(i).Cells(2).Value = ""
DataGridView1.Rows(i).Cells(3).Value = ""
DataGridView1.Rows(i).Cells(4).Value = ""
DataGridView1.Rows(i).Cells(5).Value = ""
DataGridView1.Rows(i).Cells(6).Value = ""
Next
Poll_FreeThread()
End Sub
Private Sub Poll_FreeThread()
For i As Integer = 0 To DataGridView1.Rows.Count - 1
Dim test As New testclass
test.index = i
test.testDel = AddressOf UIUpdate
Interlocked.Increment(threadcount)
Me.Label2.Text = threadcount
Try
Dim thPoll As New Thread(Sub() invokeUIUpdate(test))
thPoll.IsBackground = True
thPoll.Priority = ThreadPriority.BelowNormal
thPoll.Start()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
End Sub
Public Sub invokeUIUpdate(test As Object)
If DataGridView1.InvokeRequired Then
DataGridView1.Invoke(New testclassDelegate(AddressOf UIUpdate), test)
Else
UIUpdate(test)
End If
End Sub
Public Sub UIUpdate(test As Object)
Thread.Sleep(test.index * 100)
DataGridView1.Rows(test.index).Cells(1).Value = test.TestVal1
Me.Refresh()
Thread.Sleep(100)
DataGridView1.Rows(test.index).Cells(2).Value = test.TestVal2
Me.Refresh()
Thread.Sleep(100)
DataGridView1.Rows(test.index).Cells(3).Value = test.TestVal3
Me.Refresh()
Thread.Sleep(100)
DataGridView1.Rows(test.index).Cells(4).Value = test.TestVal4
Me.Refresh()
Thread.Sleep(100)
DataGridView1.Rows(test.index).Cells(5).Value = test.TestVal5
Me.Refresh()
Thread.Sleep(100)
DataGridView1.Rows(test.index).Cells(6).Value = test.TestVal6
Me.Refresh()
Interlocked.Decrement(threadcount)
Me.Label2.Text = threadcount
End Sub
End Class