Results 1 to 11 of 11

Thread: [SOLVED] BGW Problems? cross thread calls

  1. #1

    Thread Starter
    Lively Member polecat's Avatar
    Join Date
    Jul 2005
    Location
    Wolverhampton
    Posts
    83

    Resolved [SOLVED] BGW Problems? cross thread calls

    Hi been a while since I played !

    Right here goes I was playing and moved tome code to use a background worker. I dropped a backgroundworker on my form Set workerreportsprogress to true and the workersupportscancellation to true.....

    The first time i call the BGW all is ok but any other calls to the BGW i get
    InvalidOperationException with the message, "Control control name accessed from a thread other than the thread it was created on." in the

    ShowDrivesWorker_ProgressChanged sub

    vb Code:
    1. Private Sub ShowDrivesWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles ShowDrivesWorker.ProgressChanged
    2.  
    3.         Me.ToolStripProgressBar1.Value = e.ProgressPercentage
    4.         Me.ToolStripStatusLabel1.Text = "Finding Removable Drives"
    5.         Me.ComboBox1.Items.Add(e.UserState)
    6.         nocard = False
    7.         Me.Button1.Enabled = True
    8.  
    9.     End Sub
    10.  
    11.     Private Sub ShowDrivesWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles ShowDrivesWorker.RunWorkerCompleted
    12.  
    13.         Me.ToolStripProgressBar1.Value = 0
    14.         Me.ToolStripStatusLabel1.Text = "Ready"
    15.  
    16.         Me.ShowDrivesWorker.CancelAsync()
    17.  
    18.     End Sub

    Why would I not be able to access controls on the form from ShowDrivesWorker_ProgressChanged sub?

    Any help would be great first time use of BGW
    Last edited by polecat; Dec 21st, 2008 at 09:04 AM. Reason: Solved

  2. #2
    Hyperactive Member
    Join Date
    Mar 2002
    Location
    Boston, MA
    Posts
    391

    Re: [2005] BGW Problems? cross thread calls

    can you show us how you're invoking the background worker?

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: [2005] BGW Problems? cross thread calls

    First up, why are you calling CancelAsync in the RunWorkerCompleted event handler? The work has already completed by that stage so what are you cancelling?

    Secondly, we really need to see your DoWork event handler to be able to answer this question.

  4. #4

    Thread Starter
    Lively Member polecat's Avatar
    Join Date
    Jul 2005
    Location
    Wolverhampton
    Posts
    83

    Re: [2005] BGW Problems? cross thread calls

    I just put the CancelAsync in the RunWorkerCompleted event as a test

    im calling the BGW in my form load event

    Code:
    'Call BGW
    ShowDrivesWorker.RunWorkerAsync()
    My DoWork runs a loop and calls ShowDrivesWorker.ReportProgress
    does not touch any controls

    Code:
    Private Sub ShowDrivesWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles ShowDrivesWorker.DoWork
    
            Const Removable As Integer = 2
    
    
            Dim Scope As ManagementScope = New ManagementScope(ManagementPath.DefaultPath)
    
            Dim Query As New SelectQuery("Win32_LogicalDisk")
    
            Dim Searcher As New ManagementObjectSearcher(Scope, Query)
    
            Dim Iterator As ManagementObject
    
            Dim si As Integer = 0
    
            For Each Iterator In Searcher.Get()
    
                If Iterator.Item("DriveType").ToString = Removable.ToString Then
                    si = si + 10
                    Dim item As String = Iterator.Item("DeviceID").ToString & "\"
                    ShowDrivesWorker.ReportProgress(si, item)
                    nocard = False
    
                End If
            Next
    
            If nocard = True Then
                MessageBox.Show("Please insert your card reader!" & vbCrLf & "No USB Reader Found", "No SD Card found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    
            End If
    
    End Sub
    First time it works in the form load but if I call ShowDrivesWorker.RunWorkerAsync() again I get the errors in the update sub..

    Many thanks for looking

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: [2005] BGW Problems? cross thread calls

    When you call RunWorkerAsync the second time you aren't calling it from a background thread are you? The ProgressChanged event is marshaled to the thread on which RunWorkerAsync was called so if that wasn't the UI thread then you can't access controls in the ProgressChanged event handler. RunWorkerAsync should ONLY be called from a thread that owns the controls you want to access, which basically means only the UI thread.

    Also, you should not be calling MessageBox.Show in the DoWork event handler. A message box is supposed to be a modal dialogue but if you display it on a background thread it will NOT prevent you accessing the calling for. As such the user could conceivably ignore that message and your background thread would never complete. You should be displaying that message from the RunWorkerCompleted event handler. You can use the e.Result property to pass a value that indicates the result. Follow the BackgroundWorker link in my signature for an example.

  6. #6

    Thread Starter
    Lively Member polecat's Avatar
    Join Date
    Jul 2005
    Location
    Wolverhampton
    Posts
    83

    Re: [2005] BGW Problems? cross thread calls

    Again the msgbox's were just for me to see what was going on without using breakpoints and will be removed.

    ERM you know what jmcilhinney your right on yes it is another bg thread calling the RunWorkerAsync .... Damn how do i get around that?

    Create a new public sub that calls the RunWorkerAsync then call the new sub from bg thread ?

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: [2005] BGW Problems? cross thread calls

    Assuming you do need to start the background thread from a background thread, you have two choices that I can see:

    1. Invoke a method on the UI thread to start the BackgroundWorker. That's pretty simple if you follow the instructions in my Controls & Multithreading link.

    2. Don't use a BackgroundWorker at all and always use delegation to access the UI.

  8. #8
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: [2005] BGW Problems? cross thread calls

    you can use delegation AND a backgroundworker component cant you? I mean, isnt a backgroundworker just a System.Threading.Thread with a few handy properties/methods stuck onto it?
    But then having said that, thats essentially what the ReportProgress method does isnt it... it works just like a delegate sub would do. So why couldn't you just have your ReportProgress method call the RunWorkerASync method of the second bgworker in the WorkerReportsProgress event of your first bgworker?
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: [2005] BGW Problems? cross thread calls

    Quote Originally Posted by chris128
    you can use delegation AND a backgroundworker component cant you? I mean, isnt a backgroundworker just a System.Threading.Thread with a few handy properties/methods stuck onto it?
    But then having said that, thats essentially what the ReportProgress method does isnt it... it works just like a delegate sub would do. So why couldn't you just have your ReportProgress method call the RunWorkerASync method of the second bgworker in the WorkerReportsProgress event of your first bgworker?
    You certainly can use a BackgroundWorker and delegation. The whole point of the BackgroundWorker is that you don't have to though, so if you don't use the ProgressChanged and/or RunWorkerCompleted events then using a BackgroundWorker is pretty pointless. You might use those events AND some explicit delegation though.

    I will pull you up on one point though because it's a misconception that a lot of people have. a BackgroundWorker is NOT a Thread and it's nothing like a Thread. The BackgroundWorker is a component that hides some of the complexity of multi-threading by handling it internally for you. You call RunWorkerAsync and it will raise its DoWork event on a thread pool thread. Your DoWork event handler then gets executed on that thread, just like if you'd called ThreadPool.QueueUserWorkItem. You call ReportProgress and the BackgroundWorker handles the delegation internally and raises its ProgressChanged event on whatever thread it was started on. Your ProgressChanged event handler is then executed on the same thread you called RunWorkerAsync on. The same goes for the RunWorkerCompleted event. It gets raised when the work is done and, again, the BGW handles the delegation internally.

  10. #10
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: [2005] BGW Problems? cross thread calls

    Ah I see, thanks for the info (as always)
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  11. #11

    Thread Starter
    Lively Member polecat's Avatar
    Join Date
    Jul 2005
    Location
    Wolverhampton
    Posts
    83

    Resolved Re: [2005] BGW Problems? cross thread calls

    Sorted now guys thanks for the input had to use delegates in the end all is well

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