Я пытаюсь создать многопоточную программу для опроса компьютеров для данных, но я не могу заставить ее работать правильно. Код ниже работает и создает 4 потока, как и следовало ожидать, но поток кода, похоже, происходит последовательно и по основному потоку пользовательского интерфейса.Многопоточность Vb.net не работает ...?
То, что я пытаюсь достичь, заключается в том, что каждая строка датаграммы будет обновляться одновременно без блокировки пользовательского интерфейса.
Ниже приведена своя версия того, что у меня есть, но она служит для демонстрации проблемы. Для информации «testclass» - это класс, используемый как экземпляр машины с каждым элементом класса, представляющим свойство машины.
Надеюсь, что я дал достаточно информации, чтобы объяснить проблему. Заранее спасибо.
Пс Мне не нужно обновлять форму, если я?
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
Подсказка: Установить точку останова на 'invokeUIUpdate' и посмотреть, что произойдет с' if'. –
1. Вы проверили с _Me.InvokeRequired_ вместо _DataGridView1.InvokeRequired_? 2. Кроме того, нет необходимости вызывать _Me.Refresh() _ после установки каждого значения ячейки, вы можете поместить его только один раз после установки последнего значения ячейки. – Coder
Спасибо Раймонду. Это перешло мне в голову, но, увы, это не работало иначе, если это то, что вы имели в виду? – doovers