我正在编写一个简单的线程应用程序:单击开始按钮时,应用程序禁用此按钮,运行 5 个线程,只需进行 For 迭代并更新 5 个 ProgressBars。最后一个线程正在等待线程结束,以重新启用我的开始按钮。
问题:用户在进度条达到 100% 之前看到按钮已启用......并且进度条仍在更新!
有什么问题?有没有办法在 UI Thread 上做一个 join 语句?
这是代码:
Imports System.Threading
Public Structure ThreadParameters
Public ThreadId As Integer
Public pgBar As ProgressBar
Public iterations As Integer
End Structure
Public Structure SetPgValueParameters
Public pgBar As ProgressBar
Public value As Integer
End Structure
Public Class Form1
Private threads(4) As Thread
Private Shared FormThread As Thread
Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click
StartButton.Enabled = False
Dim MainThread As Thread = New Thread(AddressOf WaitThreads)
MainThread.Start()
For i = 0 To 4
threads(i) = New Thread(AddressOf ThreadRun)
Dim params As ThreadParameters
params.pgBar = Me.Controls.Find("ProgressBar" & (i + 1), False)(0)
params.iterations = 100
params.ThreadId = i
threads(i).Start(params)
Next
End Sub
Private Sub ThreadRun(params As ThreadParameters)
Dim invokeParams As SetPgValueParameters
Dim lastIntegerVal As Integer = 1
invokeParams.pgBar = params.pgBar
For i = 0 To params.iterations
invokeParams.value = (100 * i / params.iterations)
setPgValue(invokeParams)
Console.WriteLine(params.ThreadId & ":" & i & "/" & params.iterations)
Next
End Sub
Private Delegate Sub setPgValueDelegate(params As SetPgValueParameters)
Private Sub setPgValue(params As SetPgValueParameters)
If params.pgBar.InvokeRequired Then
Dim d As New setPgValueDelegate(AddressOf setPgValue)
Me.Invoke(d, New Object() {params})
Else
params.pgBar.Value = params.value
'Application.DoEvents()
End If
End Sub
Private Sub WaitThreads()
For i = 0 To 4
threads(i).Join()
Next
FormThread.Join()
setButtonEnabled()
End Sub
Private Delegate Sub setButtonEnabledDelegate()
Private Sub setButtonEnabled()
If StartButton.InvokeRequired Then
Dim d As New setButtonEnabledDelegate(AddressOf setButtonEnabled)
Me.Invoke(d, Nothing)
Else
Application.DoEvents()
StartButton.Enabled = True
Console.WriteLine("Bouton réactivé")
End If
End Sub
End Class
编辑:感谢链接 Bjørn-Roger Kringsjå。所以有一个解决方法:增加并直接减少值跳过动画。对于最大值,将其设置为最大值,减1,加1...仍然有一点滞后,但是确实比在ProgressBars在中间时启用按钮要好:)