Reputation: 737
My code works but I am in doubt of what I did because i set CheckForIllegalCrossThreadCalls to false which I think would give some side-effects to my backgroundworker. Here is my sample code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub go_Click(sender As Object, e As EventArgs) Handles go.Click
Try
If BackgroundWorker1.IsBusy <> True Then
BackgroundWorker1.RunWorkerAsync()
resetevent.Set()
End If
Catch ex As Exception
End Try
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Do
Label1.Text = x
Label2.Text = Label1.Text
Label3.Text = Label2.Tex
Label4.Text = Label3.Text
Label5.Text = Label4.Text
x+=1
Loop While (x < 100)
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Try
Catch ex As Exception
End Try
End Sub
Private Sub BackgroundWorker1_Completed(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Try
Catch ex As Exception
End Try
End Sub
Is there a way for me to set values to labels inside a backgroundworker without setting CheckForIllegalCrossThreadCalls to False? Because I have experienced some bugs with my program where the loop suddenly stops even if the counter limit has not been reached yet.
Upvotes: 1
Views: 8617
Reputation: 111
Something like this is a single line and works.
Label1.Invoke(Sub() Label1.Text = "Meow")
Upvotes: 1
Reputation: 250
Just add this line of code on your Form.Load, it should be fine.
Control.CheckForIllegalCrossThreadCalls = False
Upvotes: 0
Reputation: 527
Create the method
Private Sub setLabelTxt(ByVal text As String, ByVal lbl As Label)
If lbl.InvokeRequired Then
lbl.Invoke(New setLabelTxtInvoker(AddressOf setLabelTxt), text, lbl)
Else
lbl.Text = text
End If
End Sub
Private Delegate Sub setLabelTxtInvoker(ByVal text As String, ByVal lbl As Label)
and call setLabelTxt in DoWork.
EDIT: I will add the explanation a bit later with references as I am a bit busy right now. I had your problem also and this worked for me.
EDIT:
"The way to safely access controls from worker threads is via delegation. First you test the InvokeRequired property of the control, which will tell you whether or not you can safely access the control. InvokeRequired is one of the few members of the Control class that is thread-safe, so you can access it anywhere. If the property is True then an invocation is required to access the control because the current method is executing on a thread other than the one that owns the control's Handle.
The invocation is performed by calling the control's Invoke or BeginInvoke method. You create a delegate, which is an object that contains a reference to a method. It is good practice to make that a reference to the current method. You then pass that delegate to the Invoke or BeginInvoke method. That will essentially call the referenced method again, this time on the thread that owns the control's Handle."
Source: jmcilhinney post Accessing Controls from Worker Threads http://www.vbforums.com/showthread.php?498387-Accessing-Controls-from-Worker-Threads
I can't explain better than him as I'm a noob also
Upvotes: 8
Reputation: 13248
During the ProgressChanged
event, you can access the UI as it states in the MSDN documentation:
The ProgressChanged event handler executes on the thread that created the BackgroundWorker.
Thus, if you created the BackGroundWorker
on the UI thread, you can update the UI, eliminating your need to CheckForIllegalCrossThreadCalls
Source:
Upvotes: 3