For a while now I have been using this code:
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
This code runs fine, except its not Multithreading my Application and puts it into a Unresponsive State.
My Question is simple,
If InvokeRequired Then
Invoke(New UpdateDelegate(AddressOf SetLabelText2))
Else
FunctionCall1()
FunctionCall2()
FunctionCall3()
End If
they all work and take ahold of my UI Thread.
I have been searching for quite some time now, any help is appreciated.
-Edit- Also having issues while in a thread to read information from a form ... thanks for the help so far
EDIT ---
Ok, I have change my code around to look like
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
This piece of code is being called with setForm1PrgBarPerformStep(1) ' or 0
Which is called by my thread, (It works (the threading part - which is awesome btw), with the minor flaw of NOT doing the Perform Step - or any other UI changes I Code in the Private Sub setForm1PrgBarPerformStep()
Is there a good reason for this?
When your thread first hits SetLabelText2, InvokeRequired will be true so
Invoke(New UpdateDelegate(AddressOf SetLabelText2))
will be called.
Now, what actually happens inside the Invoke call is that your thread is going to pass the delegate to the UI thread as a task. So the second, recursive call to SetLabelText2 will be done by the UI thread and your thread just sits and waits for the UI thread to return from SetLabelText2. So your UI blocks because the UI thread will be in a loop, setting the label text and sleeping, and doesn't get a chance to process messages/events.
As a solution, instead of Sleep(200) you can call Application.DoEvents() inside your loop, but this may have side effects and is not recommended.
A better solution is to restrict Invoke to the strictly necessary UI calls, in your example:
Private Sub SetLabelText2()
For i = 1 To 110
'Label2.Text = Text
Invoke(MyDelegateThatDoesNothingButSettingTheLabelText)
Threading.Thread.Sleep(200)
Next
End Sub
Now the Sleeping will be done by your thread and your UI remains responsive.