Results 1 to 4 of 4

Thread: BackgroundWorker Question

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2018
    Posts
    6

    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.

  2. #2
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    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
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    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

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: BackgroundWorker Question

    Quote Originally Posted by techgnome View Post
    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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

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
  •  



Click Here to Expand Forum to Full Width