|
-
Oct 24th, 2018, 06:23 AM
#1
Thread Starter
New Member
BackgroundWorker Question
I noticed by accident that reading text from UI controls doesn't throw a "Cross thread operation not valid" error like it does if you try to change the text without using Invoke or ReportProgress inside a BackgroundWorker1_DoWork sub.
For example this code throws an error:
Code:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Textbox1.text = "Changed text"
End Sub
While this does not:
Code:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim checked as boolean = Checkbox1.Checked
Dim newString as String = Textbox1.text
End Sub
Should I continue to program inside DoWork like this since it doesn't throw an error or is there some negative to this? Should I just pass the variables through e.Argument or use Invoke instead? Is there any hidden drawbacks to either way or is it the same?
Thanks.
-
Oct 24th, 2018, 07:17 AM
#2
Re: BackgroundWorker Question
It doesn't throw an error because it's not the instance of the form you think it is... when you read the value, it created a default instance of the form ON THAT THREAD... it doesn't read from the original one... What if you had more than one instance of the form? It couldn't possibly know which one spawn the current thread. So it has no way of knowing which form to read from, so a new one on the new thread is created. You just never see it. So if there are any values from the form you need in the DoWork, they should be PASSED in, not read in... that's what the e.Arguments is for. Pass your values in, extract them out, use them, and return your value when done.
-tg
-
Oct 24th, 2018, 09:53 AM
#3
Re: BackgroundWorker Question
In theory, though, reading a variable shouldn't cause any cross-thread issues in any case...as long as the variable is visible. Writing to variables shared across threads has to be done with great care, because it's easy to get into race conditions, but reading should be thread safe. Sure, you get the state of the variable at the time of the read, which may or may not be correct, but when it comes to writing, you may or may not do the write you are expecting depending on when context switches happen.
My usual boring signature: Nothing
 
-
Oct 24th, 2018, 06:40 PM
#4
Re: BackgroundWorker Question
 Originally Posted by techgnome
It doesn't throw an error because it's not the instance of the form you think it is... when you read the value, it created a default instance of the form ON THAT THREAD... it doesn't read from the original one... What if you had more than one instance of the form? It couldn't possibly know which one spawn the current thread. So it has no way of knowing which form to read from, so a new one on the new thread is created. You just never see it. So if there are any values from the form you need in the DoWork, they should be PASSED in, not read in... that's what the e.Arguments is for. Pass your values in, extract them out, use them, and return your value when done.
-tg
I don't think that's right. If you were using the default instance then it would create a new instance on that thread but that's not the case here. That code is using an implicit Me:
Code:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim checked as boolean = Me.Checkbox1.Checked
Dim newString as String = Me.Textbox1.text
End Sub
so it's definitely using the current instance rather than the default instance. I think that it's as Shaggy says and that reading data across threads is allowed while writing it is not.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|