我正在尝试多线程。创建线程后,我的UI似乎冻结,因为我正在尝试加入创建的线程。如果我不加入我的线程,那么一切似乎都有效。
以下是我的代码。
Public Class FrmGraphWithThreads
Dim t As Thread
Dim tlist As List(Of Thread)
Private Sub FrmGraphWithThreads_Load(sender As Object, e As EventArgs) Handles MyBase.Load
UpdateTextDelegate = New UpdateTextSub(AddressOf UpdateText)
tlist = New List(Of Thread)
End Sub
#Region " Delegate and Delegate SUB to update Text Box "
Private Delegate Sub UpdateTextSub(ByRef txtbx As TextBox, ByVal val As String)
Private UpdateTextDelegate As UpdateTextSub
Private Sub UpdateText(ByRef txtbx As TextBox, ByVal val As String)
txtbx.Text = val
End Sub
#End Region
Private Sub CalculateTable(ByVal itm As Object)
Dim _int = CInt(itm)
Dim i As Integer
If _int > 0 Then
Select Case _int
Case 1
For i = 1 To 10
Dim _val = _int * i
txtBx1.Invoke(UpdateTextDelegate, New Object() {txtBx1, _val.ToString})
Thread.Sleep(1000)
Next
Case 2
For i = 1 To 10
Dim _val = _int * i
txtBx2.Invoke(UpdateTextDelegate, New Object() {txtBx2, _val.ToString})
Thread.Sleep(1000)
Next
End Select
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
For i = 1 To 2
t = New Thread(AddressOf CalculateTable)
t.Name = i.ToString
t.Start(i)
tlist.Add(t)
Thread.Sleep(10)
Next
For Each itm As Thread In tlist
itm.Join()'This causes freezing. Without join everything is working.
Next
End Sub
End Class
任何想法都会有很大的帮助。
答案 0 :(得分:1)
您正在从UI线程调用Thread.Join
。这意味着UI线程被阻塞,直到所有其他线程完成。这是一个坏主意一般,因为这意味着您的UI被阻止,而所有其他线程都可以工作。
在这种情况下,它比一个坏主意更糟糕 - 它会死锁,因为你从其他线程调用Control.Invoke
,例如:
txtBx2.Invoke(UpdateTextDelegate, New Object() {txtBx2, _val.ToString})
Control.Invoke
阻止调用线程,直到UI执行了给定的委托。所以你有后台线程被阻塞,直到UI线程完成工作,并且UI线程被阻塞,直到后台线程完成。死锁。
您几乎肯定会考虑使用async / await和tasks来代替此手动线程。它会让你的生活更轻松。