dcsimg
Results 1 to 6 of 6

Thread: What data does the Background Worker have access to?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Mar 2015
    Posts
    73

    What data does the Background Worker have access to?

    I'm running a windows forms app and using a background worker. I know that since the background worker is on a different thread it doesn't have access to UI controls, but I then I noticed that I do have access to other form members. In the example below I have access to the form member file1 but not the form member button1:


    Code:
    public partial class Form1 : Form
    {
    
            private string file1;
    
            ...
    
            private System.Windows.Forms.Button button1; //from the designer file
    
    }
    
    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    {
    
        //I have access to file1 but not button1
    }

    I would've thought that since they are both members of the same class that the access would be the same.

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    33,916

    Re: What data does the Background Worker have access to?

    Threads have access to any non-local variable that is in scope. Technically, they even have access to UI elements like controls, but this can cause some really bad side effects, so it is prevented. In other words, the fact that the BGW can't access UI elements is the exception, not the rule.

    This has some odd ramifications. If the UI and the BGW are both working with some form level variable, you have to be careful to avoid harmful interactions. If either one is ONLY reading the variable, then there shouldn't be an issue, but if both threads will be writing to it, then you need to control access. In the case of a file, I wouldn't want both threads to be even trying to both read from it at the same time, though that should theoretically cause no problems.
    My usual boring signature: Nothing

  3. #3
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    102,575

    Re: What data does the Background Worker have access to?

    It is not true to say that the BackgroundWorker is on a different thread. The BackgroundWorker isn't on any thread. It's just an object. When you call RunWorkerAsync, it raises its DoWork event on a ThreadPool thread. If you have registered a method as a handler for that event, that method gets executed on that thread. The DoWork event handler is part of the form, not of the BackgroundWorker. It is a method of the form that is executed on a background thread.

    Just like any other method of that form, the DoWork event handler can access any member of the form. There's no issue writing code that accesses a control in that method because the compiler has no idea at design time what thread the code will be executed on. It's only at run time that you'll encounter an issue. When you run that code in the debugger, a cross-thread exception will be thrown. That's because you're not supposed to access the handle of a control on a thread other than the one it was created on. It actually is possible to access a control's handle on a secondary thread without issue but only sometimes. To avoid the times that it's problem, just don't do it ever. If you run a Release build of your code, no cross-thread exception will be thrown but other issues may arise. In Debug mode, the exception is thrown by default but you can alter that behaviour by setting a property. Don't do that.

    When using a BackgroundWorker, do as intended and touch the UI only in the ProgressChanged and RunWorkerCompleted event handlers. Again, they are part of the form, not of the BackgroundWorker, and are executed on the UI thread.

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Mar 2015
    Posts
    73

    Re: What data does the Background Worker have access to?

    Quote Originally Posted by Shaggy Hiker View Post
    Threads have access to any non-local variable that is in scope. Technically, they even have access to UI elements like controls, but this can cause some really bad side effects, so it is prevented. In other words, the fact that the BGW can't access UI elements is the exception, not the rule.

    This has some odd ramifications. If the UI and the BGW are both working with some form level variable, you have to be careful to avoid harmful interactions. If either one is ONLY reading the variable, then there shouldn't be an issue, but if both threads will be writing to it, then you need to control access. In the case of a file, I wouldn't want both threads to be even trying to both read from it at the same time, though that should theoretically cause no problems.
    Ok, that makes sense. You still have access to all variables in scope but you don't want to be messing around with them at the same time.

    Maybe the best way would be to just pass in everything you need to the DoWork method just to be consistent (and not take any chances)?

  5. #5
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    102,575

    Re: What data does the Background Worker have access to?

    Quote Originally Posted by madison320 View Post
    Maybe the best way would be to just pass in everything you need to the DoWork method just to be consistent (and not take any chances)?
    The best option is to understand what your code is doing and where the specific cases are that could cause an issue and handle each of those issues in the best way for that issue. That might be passing something in via the RunWorkerAsync call or it might not.

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    33,916

    Re: What data does the Background Worker have access to?

    If it is possible to make local copies, then that can be easier on the mind. It is often not possible to make local copies, and not everything passed in would be totally safe, either. After all, passing in a reference type would just mean passing in a copy of the reference.

    Therefore, I agree with JMC. Threading can be hard to get ones head around. In general, I use BGWs for processes that are clearly related to a form (in which case that report progress event can be mighty convenient), and processes that have only a single instance. For example, if I wanted to have five different threads doing (roughly) the same thing, I wouldn't use a BGW, but would probably use a Task. If the background process was not conceptually related to the form that launched it, then I'd be inclined to use a Thread, even though that could mean that I'd have to do a bit more work communicating back to the UI thread. An example of this would be something like a UDP communicator. Such a thing might be created and/or launched from a form, but it isn't conceptually part of a form, so I'd use a Thread, even though a BGW could be used.

    In general, though, you want any other thread to interact with other threads as little as possible. It's not just that you could miss locking something and create an inadvertent race condition, but even if you were properly locking and releasing shared resources, you are creating bottlenecks at which the threads might contend for the same resource. Get enough of those, or get them in just the wrong place, and you run the risk of throwing out any gain from threading, or even make a threaded program slower than a non-threaded program that did the same thing. If every thread has to wait its turn at the same spot, and each thread does, in fact, end up waiting, then that bottleneck is slowing EVERYTHING down. So, reducing the sharing of data does have advantages. Of course, it can have costs, too.

    Threading is not a panacea. It can speed some programs up, but it can also slow other programs down.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width