我已经使用这段代码有一段时间了:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim t2 As New Threading.Thread(AddressOf SetLabelText2)
t2.IsBackground = True
t2.Start()
End Sub
Delegate Sub UpdateDelegate()
Private Sub SetLabelText2()
If InvokeRequired Then
Invoke(New UpdateDelegate(AddressOf SetLabelText2))
Else
For i = 1 To 110
Label2.Text = Text
Threading.Thread.Sleep(200)
Next
End If
End Sub
此代码运行良好,但它不是对我的应用程序进行多线程处理并将其置于无响应状态。
我的问题很简单,
If InvokeRequired Then
Invoke(New UpdateDelegate(AddressOf SetLabelText2))
Else
FunctionCall1()
FunctionCall2()
FunctionCall3()
End If
它们都可以工作并占据我的 UI 线程。
我已经搜索了很长一段时间了,非常感谢任何帮助。
-编辑- 在线程中从表单中读取信息时也遇到问题...感谢迄今为止的帮助
编辑---
好吧,我已经改变了我的代码,看起来像
Delegate Sub setForm1PrgBarPerformStepdelegate(s As Integer)
Private Sub setForm1PrgBarPerformStep(ByVal s As Integer)
If Form1.ProgressBar1.InvokeRequired Then
Dim d As New setForm1lblAlltextdelegate(AddressOf setForm1PrgBarPerformStep)
Form1.Invoke(d, New Object() {s})
Else
If s = 1 Then
Form1.ProgressBar1.PerformStep()
Else
End If
End If
End Sub
这段代码正在使用 setForm1PrgBarPerformStep(1) ' 或 0 来调用
这是由我的线程调用的,(它可以工作(线程部分 - 顺便说一句,这很棒),但有一个小缺陷,即不执行执行步骤 - 或我在 Private Sub setForm1PrgBarPerformStep() 中编码的任何其他 UI 更改
这有充分的理由吗?
当你的线程第一次点击 SetLabelText2 时,InvokeRequired 将为 true 所以
Invoke(New UpdateDelegate(AddressOf SetLabelText2))
将会被召唤。
现在,Invoke 调用中实际发生的事情是您的线程将委托作为任务传递给 UI 线程。因此,对 SetLabelText2 的第二次递归调用将由 UI 线程完成,您的线程只是等待 UI 线程从 SetLabelText2 返回。所以你的 UI 会阻塞,因为 UI 线程将处于循环中,设置标签文本并休眠,并且没有机会处理消息/事件。
作为解决方案,您可以在循环内调用 Application.DoEvents(),而不是 Sleep(200),但这可能会产生副作用,不建议这样做。
更好的解决方案是将 Invoke 限制为严格必要的 UI 调用,在您的示例中:
Private Sub SetLabelText2()
For i = 1 To 110
'Label2.Text = Text
Invoke(MyDelegateThatDoesNothingButSettingTheLabelText)
Threading.Thread.Sleep(200)
Next
End Sub
现在睡眠将由您的线程完成,并且您的 UI 保持响应。
您的第一个问题是,由于 Invoke,SetLabelText2 中的 Sleep 是在 UI 线程上调用的,而不是在后台线程上调用的。这将导致 UI 显示为锁定。新线程仅用于启动 SetLabel,但工作几乎立即返回到调用线程。相反,您需要调用循环内的后台任务,并将每个标签更新委托回 UI。
其次,您不应该在此示例中创建显式线程。从 .Net 4 开始,您应该改用任务。要像使用 Thread.Sleep 那样模拟长时间运行的操作,请使用 Task.Delay(200),然后对其进行 Await 或显式调用 .Wait。请记住在后台线程上安排延迟并委托回来进行 UI 更新。
好的,感谢本节中提出的评论以及一些研究的帮助,我终于弄清楚了。
我有点作弊,通过运行 UI 线程,只在循环中或只是短时间内完成繁重的工作,这里有一些代码 - 希望这对其他人有帮助。
Public t2 As Threading.Thread ' Instantiating the Thread. I do this in my Modules
' You will want to do this for all threads needed.
'You would then go through your program like normal until you hit a heavy process eating point,
'For me it was when i was converting images and sending them / moving them across the network
'So to get what i wanted i used this in the middle of my public Function
For Each s As String In sFiles
c += 1 'This was just a simple file counter for the prg bar
CheckAgain:
If t3 Is Nothing Then
t3 = New Thread(New ParameterizedThreadStart(AddressOf DoWork))
t3.Start(s)
GoTo NextOne
ElseIf t4 Is Nothing Then
t4 = New Thread(New ParameterizedThreadStart(AddressOf DoWork))
t4.Start(s)
GoTo NextOne
ElseIf t5 Is Nothing Then
t5 = New Thread(New ParameterizedThreadStart(AddressOf DoWork))
t5.Start(s)
GoTo NextOne
ElseIf t6 Is Nothing Then
t6 = New Thread(New ParameterizedThreadStart(AddressOf DoWork))
t6.Start(s)
GoTo NextOne
ElseIf t7 Is Nothing Then
t7 = New Thread(New ParameterizedThreadStart(AddressOf DoWork))
t7.Start(s)
GoTo NextOne
ElseIf t8 Is Nothing Then
t8 = New Thread(New ParameterizedThreadStart(AddressOf DoWork))
t8.Start(s)
GoTo NextOne
ElseIf t9 Is Nothing Then
t9 = New Thread(New ParameterizedThreadStart(AddressOf DoWork))
t9.Start(s)
GoTo NextOne
Else
GoTo CheckAgain
End If
NextOne:
Next
Sub DoWork(ByVal s As Object)
ChangeCompression("Variables for my Function that did alot of work")
'System.Threading.Thread.Sleep(10)
'This is how i disposed of my threads
If Not (t3 Is Nothing) Then
t3 = Nothing
ElseIf Not (t4 Is Nothing) Then
t4 = Nothing
ElseIf Not (t5 Is Nothing) Then
t5 = Nothing
ElseIf Not (t6 Is Nothing) Then
t6 = Nothing
ElseIf Not (t7 Is Nothing) Then
t7 = Nothing
ElseIf Not (t8 Is Nothing) Then
t8 = Nothing
ElseIf Not (t9 Is Nothing) Then
t9 = Nothing
End If
End Sub
这就是全部了:) - 希望这可以帮助某人,并感谢所有人帮助我完成我的 - 有点多线程,是的......我知道有更好的方法,但这个对我有用:)