Page 1 of 3 123 LastLast
Results 1 to 40 of 91

Thread: Using the BackgroundWorker Component

  1. #1

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Using the BackgroundWorker Component

    C# version here.

    Create a new Windows Forms project. Add a Label, a ProgressBar and a BackgroundWorker to the form. Set the BackgroundWorker's WorkerReportsProgress property to True. Add the following code then run the project.
    VB.NET Code:
    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2.     'Raise the DoWork event in a worker thread.
    3.     Me.BackgroundWorker1.RunWorkerAsync()
    4. End Sub
    5.  
    6. 'This method is executed in a worker thread.
    7. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
    8.                                      ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    9.     Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    10.  
    11.     For i As Integer = 1 To 100
    12.         'Raise the ProgressChanged event in the UI thread.
    13.         worker.ReportProgress(i, i & " iterations complete")
    14.  
    15.         'Perform some time-consuming operation here.
    16.         Threading.Thread.Sleep(250)
    17.     Next i
    18. End Sub
    19.  
    20. 'This method is executed in the UI thread.
    21. Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
    22.                                               ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    23.     Me.ProgressBar1.Value = e.ProgressPercentage
    24.     Me.Label1.Text = TryCast(e.UserState, String)
    25. End Sub
    26.  
    27. 'This method is executed in the UI thread.
    28. Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
    29.                                                  ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    30.     Me.Label1.Text = "Operation complete"
    31. End Sub

  2. #2

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Passing Data to be Used in the Worker Thread.

    E.g. Perform a loop in the worker thread with a number of iterations determined by the value set in a NumericUpDown:
    VB.NET Code:
    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2.     Me.BackgroundWorker1.RunWorkerAsync(CInt(Me.NumericUpDown1.Value))
    3. End Sub
    4.  
    5. Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
    6.                                      ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    7.     Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
    8.     Dim iterationCount As Integer = 0
    9.  
    10.     If TypeOf e.Argument Is Integer Then
    11.         iterationCount = CInt(e.Argument)
    12.     End If
    13.  
    14.     For i As Integer = 1 To iterationCount Step 1
    15.         'Do something here.
    16.     Next i
    17. End Sub

  3. #3
    Just Married shakti5385's Avatar
    Join Date
    Mar 2006
    Location
    Udaipur,Rajasthan(INDIA)
    Posts
    3,747

    Re: Using the BackgroundWorker Component

    How to fill multiple combo using the background worker component!

    I done this for a single combo but for the multiple combo it is not working!
    Please guide me


    VB.NET Code:
    1. Private Sub BackgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork
    2.         Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    3.         rawMaterialCategoryDataTable = rawMaterialCategory.ReturnDataTable(, "ORDER BY CategoryName") 'Returnning a Datatable
    4.         Dim dataColumn As New DataColumn
    5.         dataColumn.DataType = GetType(Integer)
    6.         dataColumn.ColumnName = "SearchingCode"
    7.         Dim searchingCode As Integer
    8.         rawMaterialCategoryDataTable.Columns.Add(dataColumn)
    9.         For Each dataRow As DataRow In rawMaterialCategoryDataTable.Rows
    10.             worker.ReportProgress(0, dataRow("CategoryName"))
    11.             rawMaterialCategoryDataTable.Rows(searchingCode).Item("SearchingCode") = searchingCode + 1
    12.             searchingCode += 1
    13.         Next dataRow
    14.     End Sub
    15.  
    16.     Private Sub BackgroundWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker.ProgressChanged
    17.         If Not e.UserState Is Nothing Then
    18.             Me.sRawMaterialCategory.Items.Add(CStr(e.UserState).Trim) 'Adding In the combo Box
    19.         Else
    20.             'Me.ProgressBar1.Value = e.ProgressPercentage
    21.         End If
    22.     End Sub

  4. #4

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Here are two examples that contrast using a BackgroundWorker to update the UI as the work is done and using it to update the UI only once the work is complete:
    vb.net Code:
    1. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
    2.                                      ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    3.     Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
    4.  
    5.     For Each filePath As String In IO.Directory.GetFiles(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
    6.         worker.ReportProgress(0, IO.Path.GetFileName(filePath))
    7.     Next filePath
    8. End Sub
    9.  
    10. Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
    11.                                               ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    12.     Dim fileName As String = DirectCast(e.UserState, String)
    13.  
    14.     Me.ListBox1.Items.Add(fileName)
    15. End Sub
    vb.net Code:
    1. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
    2.                                      ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    3.     Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
    4.     Dim fileNames As String() = IO.Directory.GetFiles(My.Computer.FileSystem.SpecialDirectories.MyDocuments)
    5.  
    6.     For index As Integer = 0 To fileNames.GetUpperBound(0) Step 1
    7.         fileNames(index) = IO.Path.GetFileName(fileNames(index))
    8.     Next index
    9.  
    10.     e.Result = fileNames
    11. End Sub
    12.  
    13. Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
    14.                                                  ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    15.     Dim fileNames As String() = DirectCast(e.Result, String())
    16.  
    17.     Me.ListBox1.Items.AddRange(fileNames)
    18. End Sub
    These examples show how you can pass data to the UI from a BackgroundWorker in two different ways without having to explicitly delegate, which is one of the first things everyone has trouble with when multi-threading.

    Note that for the first example to work the WorkerReportsProgress property must be set to True.

  5. #5
    Addicted Member
    Join Date
    Mar 2008
    Posts
    150

    Re: Using the BackgroundWorker Component

    I am trying to follow your first post and I get this error:

    "This BackgroundWorker states that it doesn't report progress. Modify WorkerReportsProgress to state that it does report progress."

    Everything works okay when I comment out the line that errors...

    Do you have the quick solution to this problem?

    Nicely done all the same. Cheers.

  6. #6

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by scootabug
    I am trying to follow your first post and I get this error:

    "This BackgroundWorker states that it doesn't report progress. Modify WorkerReportsProgress to state that it does report progress."

    Everything works okay when I comment out the line that errors...

    Do you have the quick solution to this problem?

    Nicely done all the same. Cheers.
    The error message says this:
    Modify WorkerReportsProgress to state that it does report progress.
    In post #1 I said this:
    Set the BackgroundWorker's WorkerReportsProgress property to True.
    In post #4 I said this:
    Note that for the first example to work the WorkerReportsProgress property must be set to True.
    Are you noticing a theme here?

  7. #7
    Addicted Member
    Join Date
    Mar 2008
    Posts
    150

    Re: Using the BackgroundWorker Component

    Sorry, my bad. I noticed the property after I'd posted, hadn't got a chance to come back here until now to say 'nevermind!'. Thanks though, you are invaluable.

  8. #8
    Lively Member
    Join Date
    May 2008
    Posts
    75

    Re: Using the BackgroundWorker Component

    thanks for the outline., it helped me understand the concept of using dowork with triggering RunWorkerCompleted and progresschanged..

    question... this was posted in 2007.. im guessing it has not really for .net 3.5... is it?

    now., is it possible to tie in the background worker with the calls to a webservice? im sure there is.. i know i have seen the async calls somewhere., possibly with the buffer = false?.. i ask because... i have a handheld device, that queries a webservice for a dataset, the webservice generates the dataset, and it has around 20,000 records... surprisingly., it generates the data in about a minute,. and then the device inserts the data into its sqlce db.. so, im wondering if there is a way to turn off buffering on the webserice call and populate the database as data comes back... rather than., send command-> wait for entire dataset -> insert data set...... i want to do a send command -> wait a bit, ->do a bit -> loop a bit

    sadly i have to communicate thru a web service... client needs top security and will not allow access to db's directly from desktop/work station... all db's must be accessed thru web serivce...

  9. #9

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by zxed
    thanks for the outline., it helped me understand the concept of using dowork with triggering RunWorkerCompleted and progresschanged..

    question... this was posted in 2007.. im guessing it has not really for .net 3.5... is it?

    now., is it possible to tie in the background worker with the calls to a webservice? im sure there is.. i know i have seen the async calls somewhere., possibly with the buffer = false?.. i ask because... i have a handheld device, that queries a webservice for a dataset, the webservice generates the dataset, and it has around 20,000 records... surprisingly., it generates the data in about a minute,. and then the device inserts the data into its sqlce db.. so, im wondering if there is a way to turn off buffering on the webserice call and populate the database as data comes back... rather than., send command-> wait for entire dataset -> insert data set...... i want to do a send command -> wait a bit, ->do a bit -> loop a bit

    sadly i have to communicate thru a web service... client needs top security and will not allow access to db's directly from desktop/work station... all db's must be accessed thru web serivce...
    The BackgroundWorker class hasn't changed at all (as far as I'm aware) from .NET 2.0 to 3.5.

    My knowledge of Web Services is not extensive but, as far as I'm aware, calling a web method is essentially the same as calling a local method. If your method returns a DataSet then you can't really do anything until that method returns because you have no data until then. If you can somehow access the data piecemeal then you can certainly use it as you receive it. That's beyond the scope of this thread though. I'd suggest you post a question relating to this specifically on the appropriate forum.

  10. #10
    PowerPoster JuggaloBrotha's Avatar
    Join Date
    Sep 2005
    Location
    Lansing, MI; USA
    Posts
    4,286

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by zxed
    question... this was posted in 2007.. im guessing it has not really for .net 3.5... is it?
    The 3.5 framework literally sits on top of the 3.0 framework and the 3.0 framework literally sits on top of the 2.0 framework which means unless there's a new backgroundworker in the 3.5 framework (which you would know about it if you were using it because you would have to explicitly reference it) the only background worker is the 2.0 one.

    Another interesting tip: the 3.0 and 3.5 frameworks don't have a CLR, it's the 2.0 framework that has the CLR we all use and love.
    Currently using VS 2015 Enterprise on Win10 Enterprise x64.

    CodeBank: All ThreadsColors ComboBoxFading & Gradient FormMoveItemListBox/MoveItemListViewMultilineListBoxMenuButtonToolStripCheckBoxStart with Windows

  11. #11
    Lively Member
    Join Date
    May 2008
    Posts
    75

    Re: Using the BackgroundWorker Component

    thanks for getting back to me., i will figure out the web service thingy, and create a sep thread with code + examples.

  12. #12
    Fanatic Member
    Join Date
    Jun 2008
    Posts
    515

    Re: Using the BackgroundWorker Component

    I have a question. When a large number of files are being copied, how can I accurately show overall process progressbar feedback ? Update the form's progressbar from the backgroundworker...

    Thanks for any help.

  13. #13

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by Xancholy
    I have a question. When a large number of files are being copied, how can I accurately show overall process progressbar feedback ? Update the form's progressbar from the backgroundworker...

    Thanks for any help.
    This thread already shows you how to update a ProgressBar to indicate the progress of a background operation so I'm not going to go over that. Your issue is determining what constitutes 100% and determining what your current percentage is.

    Now, the first thing to note is that progress does NOT have to represent a percentage. You can, if you want, set the Maximum of your ProgressBar to 100 and then set the Value to a percentage. Alternatively you could set the Maximum to the number files you need to process and then increment the Value by 1 each time a file is processed. Another alternative would be to set the Maximum to the total size of all the files to be processed and then increment the Value by the size of the file each time one is processed.

  14. #14
    Fanatic Member
    Join Date
    Jun 2008
    Posts
    515

    Re: Using the BackgroundWorker Component

    OK thanks.
    Last edited by Xancholy; Jun 5th, 2008 at 08:52 PM.

  15. #15

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by Xancholy
    The other option would be to measure total of filesizes being copied and progressbar it in a linear way, yes ?
    The only time you can update the ProgressBar is after each file has been processed because copying a file is a synchronous operation. You can't provide any feedback during the copy operation.

  16. #16
    Addicted Member
    Join Date
    Mar 2007
    Posts
    177

    Re: Using the BackgroundWorker Component

    See the other post.
    Last edited by doran_doran; Jun 10th, 2008 at 10:38 AM.

  17. #17

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    doran, you're going to have to tidy that post up before I'll even consider looking at it.

  18. #18
    Addicted Member sauronsmatrix's Avatar
    Join Date
    Jun 2008
    Location
    USA
    Posts
    133

    Re: Using the BackgroundWorker Component

    I found that I didn't even need the Sleep from the Threading. The worker seems to use just the right amount of resources to get the task done without crashing or overloading.

  19. #19

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Here is a new example based on the code from the first post. Follow the same instructions as before but this time also set the WorkerSupportsCancellation property of the BackgroundWorker to True and add a Button to the form. Now add this code to your form:
    vb.net Code:
    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2.     'Raise the DoWork event in a worker thread.
    3.     Me.BackgroundWorker1.RunWorkerAsync()
    4. End Sub
    5.  
    6. 'This method is executed in a worker thread.
    7. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
    8.                                      ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    9.     Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    10.  
    11.     For i As Integer = 1 To 100
    12.         If worker.CancellationPending Then
    13.             'The user has cancelled the background operation.
    14.             e.Cancel = True
    15.             Exit For
    16.         End If
    17.  
    18.         'Raise the ProgressChanged event in the UI thread.
    19.         worker.ReportProgress(i, i & " iterations complete")
    20.  
    21.         'Perform some time-consuming operation here.
    22.         Threading.Thread.Sleep(250)
    23.     Next i
    24. End Sub
    25.  
    26. 'This method is executed in the UI thread.
    27. Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
    28.                                               ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    29.     Me.ProgressBar1.Value = e.ProgressPercentage
    30.     Me.Label1.Text = TryCast(e.UserState, String)
    31. End Sub
    32.  
    33. 'This method is executed in the UI thread.
    34. Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
    35.                                                  ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    36.     If e.Cancelled Then
    37.         'The background operation was cancelled.
    38.         Me.Label1.Text = "Operation cancelled"
    39.     Else
    40.         'The background operation completed normally.
    41.         Me.Label1.Text = "Operation complete"
    42.     End If
    43. End Sub
    44.  
    45. Private Sub Button1_Click(ByVal sender As Object, _
    46.                           ByVal e As EventArgs) Handles Button1.Click
    47.     'Only cancel the background opertion if there is a background operation in progress.
    48.     If Me.BackgroundWorker1.IsBusy Then
    49.         Me.BackgroundWorker1.CancelAsync()
    50.     End If
    51. End Sub
    If you run the project and let it go then the ProgressBar will fill and eventually the Label will report that the operation completed. If, however, you click the Button at some point, the Progressbar will halt and the Label will report that the operation was cancelled.

  20. #20
    Fanatic Member
    Join Date
    Jun 2008
    Posts
    515

    Re: Using the BackgroundWorker Component

    nice

  21. #21
    Junior Member
    Join Date
    Aug 2008
    Posts
    22

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by jmcilhinney
    Create a new Windows Forms project. Add a Label, a ProgressBar and a BackgroundWorker to the form. Set the BackgroundWorker's WorkerReportsProgress property to True. Add the following code then run the project.
    VB.NET Code:
    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2.     'Raise the DoWork event in a worker thread.
    3.     Me.BackgroundWorker1.RunWorkerAsync()
    4. End Sub
    5.  
    6. 'This method is executed in a worker thread.
    7. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
    8.                                      ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    9.     Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    10.  
    11.     For i As Integer = 1 To 100
    12.         'Raise the ProgressChanged event in the UI thread.
    13.         worker.ReportProgress(i, i & " iterations complete")
    14.  
    15.         'Perform some time-consuming operation here.
    16.         Threading.Thread.Sleep(250)
    17.     Next i
    18. End Sub
    19.  
    20. 'This method is executed in the UI thread.
    21. Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
    22.                                               ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    23.     Me.ProgressBar1.Value = e.ProgressPercentage
    24.     Me.Label1.Text = TryCast(e.UserState, String)
    25. End Sub
    26.  
    27. 'This method is executed in the UI thread.
    28. Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
    29.                                                  ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    30.     Me.Label1.Text = "Operation complete"
    31. End Sub
    hi, i used the above code .. and i got this error:

    Cross-thread operation not valid: Control 'Label1' accessed from a thread other than the thread it was created on.

    need your advise...

  22. #22

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by numbskull77
    hi, i used the above code .. and i got this error:

    Cross-thread operation not valid: Control 'Label1' accessed from a thread other than the thread it was created on.

    need your advise...
    You certainly didn't use just that code. If you go back to post #4 I specifically demonstrate how to access controls using a BackgroundWorker, i.e. either from the ProgressChanged event handler or the RunWorkerCompleted event handler. That's because they are both executed in the UI thread. You cannot access controls from the DoWork event handler, as you must be, because it is executed in a background thread.

    If you can't use those two aforementioned events for some reason then you will need to use explicit delegation. Follow the Controls & Multi-threading link in my signature for an explanation of why and how.

  23. #23
    Fanatic Member
    Join Date
    Jul 2007
    Posts
    530

    Re: Using the BackgroundWorker Component

    Hi John ,

    i have a problem with stopping the BackgroundWorker
    i have 2 button start & stop
    so basically the start button download some data using webclient

    Code:
    bgwkdata.RunWorkerAsync()
    and for stop button i have

    Code:
    bgwkdata.CancelAsync()
    so the problem is the stop button not doing the job the BackgroundWorker is still running
    btw i have set option true to Workersupportcancellation and also

    Code:
    If bgwkdata.CancellationPending Then
    
                e.Cancel = True
    
                Exit Sub
    
            End If
    Thanks
    Last edited by killer7k; Oct 31st, 2008 at 08:17 PM.

  24. #24

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by killer7k
    Hi John ,

    i have a problem with stopping the BackgroundWorker
    i have 2 button start & stop
    so basically the start button download some data using webclient

    Code:
    bgwkdata.RunWorkerAsync()
    and for stop button i have

    Code:
    bgwkdata.CancelAsync()
    so the problem is the stop button not doing the job the BackgroundWorker is still running
    btw i have set option true to Workersupportcancellation and also

    Code:
    If bgwkdata.CancellationPending Then
    
                e.Cancel = True
    
                Exit Sub
    
            End If
    Thanks
    Presumably that code is never being hit during your time-consuming operation. For instance, there's not much point doing this:
    vb.net Code:
    1. If myBGW.CancellationPending Then
    2.     e.Cancel = True
    3.     Exit Sub
    4. End If
    5.  
    6. For count As Integer = 1 To 100
    7.     'Do something.
    8. Next
    9.  
    10. If myBGW.CancellationPending Then
    11.     e.Cancel = True
    12.     Exit Sub
    13. End If
    because you don't ever check whether the operation needs to be cancelled anywhere in the loop. You'd need to check inside the loop. If you don't have a loop then you'll just have to check in between the steps of your operation. You can only check whether the operation needs to be cancelled while the background thread is not busy doing something else. If your background thread simply makes one synchronous method call then you're out of luck. It simply can't be cancelled. There need to be breaks somewhere in your code that you can insert those checks.

  25. #25
    Fanatic Member
    Join Date
    Jul 2007
    Posts
    530

    Re: Using the BackgroundWorker Component

    Hi John ,

    here you what i have done

    Code:
       Private Sub bgwkdata_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwkdata.DoWork
          
      If bgwkdata.CancellationPending Then
    
                e.Cancel = True
    
                Exit Sub
    
            End If
    
    //my boucle here
    
     If bgwkdata.CancellationPending Then
    
                e.Cancel = True
    
                Exit Sub
    
            End If
    and on btnstop :

    Code:
    Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
    
    
            bgwkdata.CancelAsync()
    
    
    
    
    
    
        End Sub
    Edit : i get it to work i placed the code in the boucle

    Thanks
    Last edited by killer7k; Nov 1st, 2008 at 11:53 AM.

  26. #26
    Hyperactive Member kuldevbhasin's Avatar
    Join Date
    Mar 2008
    Location
    Mumbai, India
    Posts
    488

    Re: Using the BackgroundWorker Component

    hi jmc
    can we use background worker on smart device application ?
    i am developing a app. in vb.net 2008 for a smart device.
    i am trying to locate the background worker that u mentioned to be added to the form but am not able to find it.
    do i have to import something to get that option or what ?
    pls. guide
    thankx a lot

  27. #27
    PowerPoster JuggaloBrotha's Avatar
    Join Date
    Sep 2005
    Location
    Lansing, MI; USA
    Posts
    4,286

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by kuldevbhasin View Post
    hi jmc
    can we use background worker on smart device application ?
    i am developing a app. in vb.net 2008 for a smart device.
    i am trying to locate the background worker that u mentioned to be added to the form but am not able to find it.
    do i have to import something to get that option or what ?
    pls. guide
    thankx a lot
    The location of the BW is this: System.ComponentModel.BackgroundWorker

    So I would start by looking for it in the System.ComponentModel namespace
    Currently using VS 2015 Enterprise on Win10 Enterprise x64.

    CodeBank: All ThreadsColors ComboBoxFading & Gradient FormMoveItemListBox/MoveItemListViewMultilineListBoxMenuButtonToolStripCheckBoxStart with Windows

  28. #28

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by kuldevbhasin View Post
    hi jmc
    can we use background worker on smart device application ?
    i am developing a app. in vb.net 2008 for a smart device.
    i am trying to locate the background worker that u mentioned to be added to the form but am not able to find it.
    do i have to import something to get that option or what ?
    pls. guide
    thankx a lot
    The CF contains less than the full Framework and the BackgroundWorker class is simply not necessary. It's convenient but it doesn't do anything you can't do yourself with the Thread class and delegates.

  29. #29
    Hyperactive Member kuldevbhasin's Avatar
    Join Date
    Mar 2008
    Location
    Mumbai, India
    Posts
    488

    Re: Using the BackgroundWorker Component

    thankx for ur reply
    i have developed a prog. for bills generation on a smart device. the smart device is using GPRS and web service to connect to the data stored on the server.
    what i was thinking was that if GPRS is not available then the prog. should generate and store the data on the device itself as sqlce is available on the device. now as soon as the GPRS is available i was thinking of sending the data to the web server in the background.
    for this reason was trying for background worker. so that while the bills get generated the local bills r also getting posted simultaniously in the background.
    am i right in this thinking or is there any other way.
    pls. guide.
    thankx

  30. #30

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by kuldevbhasin View Post
    thankx for ur reply
    i have developed a prog. for bills generation on a smart device. the smart device is using GPRS and web service to connect to the data stored on the server.
    what i was thinking was that if GPRS is not available then the prog. should generate and store the data on the device itself as sqlce is available on the device. now as soon as the GPRS is available i was thinking of sending the data to the web server in the background.
    for this reason was trying for background worker. so that while the bills get generated the local bills r also getting posted simultaniously in the background.
    am i right in this thinking or is there any other way.
    pls. guide.
    thankx
    That is not the topic of this thread. You should ask such questions in new threads in the appropriate forum.

  31. #31
    Hyperactive Member snakeman's Avatar
    Join Date
    Aug 2006
    Posts
    351

    Re: Using the BackgroundWorker Component

    hey jim
    why do you declare a new worker:-
    vb Code:
    1. Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    you already have one
    i couldn't understand it
    and why you didn't dispose the backgroundworker?

  32. #32

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by snakeman View Post
    hey jim
    why do you declare a new worker:-
    vb Code:
    1. Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    you already have one
    i couldn't understand it
    and why you didn't dispose the backgroundworker?
    There's a difference between "declaring" and "creating". That code declares a BackgroundWorker variable but it does NOT create a BackgroundWorker object. It simply takes the 'sender' parameter, which is the object that raised the event, and casts it as type BackgroundWorker. By assigning that to the local variable I am then able to access members of the BackgroundWorker type, which I couldn't do on 'sender' because it is type Object.

    Yes, I could have simply used the existing member variable, i.e. Me.BackgroundWorker1, and had the same result. The reason that casting the 'sender' is useful is that it allows you to handle events for multiple BackgroundWorkers with the same method. If you only have one BackgroundWorker then it's not required, although it is considered best practice.

  33. #33
    Hyperactive Member snakeman's Avatar
    Join Date
    Aug 2006
    Posts
    351

    Re: Using the BackgroundWorker Component

    thx jim

  34. #34
    New Member
    Join Date
    Jun 2009
    Posts
    9

    Re: Using the BackgroundWorker Component

    Cant seem to figure out what Im doing wrong here, I get a type expected error from vb when I try to compile from the first backgroundWorker part of this (it automatically makes it a lowercase "b" could that have something to do with this?)
    Code:
     Dim worker As backgroundWorker = DirectCast(sender, backgroundWorker)
    entire code
    Code:
    Public Class Form1
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            'Raise the DoWork event in a worker thread.
            Me.BackgroundWorker1.RunWorkerAsync()
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Me.BackgroundWorker1.RunWorkerAsync(CInt(Me.NumericUpDown1.Value))
        End Sub
        'This method is executed in a worker thread.
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
                                         ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Dim worker As backgroundWorker = DirectCast(sender, backgroundWorker)
            Dim iterationCount As Integer = 0
    
            If TypeOf e.Argument Is Integer Then
                iterationCount = CInt(e.Argument)
            End If
    
            For i As Integer = 1 To iterationCount Step 1
                'Do something here.
            Next i
        End Sub
    
        'This method is executed in the UI thread.
        Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
                                                            ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
            Me.ProgressBar1.Value = e.ProgressPercentage
            Me.Label1.Text = TryCast(e.UserState, String)
    
        End Sub
    
        'This method is executed in the UI thread.
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
                                                               ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            Me.Label1.Text = "Operation complete"
        End Sub
    End Class
    Thanks in advance for any help!

  35. #35

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by Tommi View Post
    Cant seem to figure out what Im doing wrong here, I get a type expected error from vb when I try to compile from the first backgroundWorker part of this (it automatically makes it a lowercase "b" could that have something to do with this?)
    Code:
     Dim worker As backgroundWorker = DirectCast(sender, backgroundWorker)
    entire code
    Code:
    Public Class Form1
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            'Raise the DoWork event in a worker thread.
            Me.BackgroundWorker1.RunWorkerAsync()
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Me.BackgroundWorker1.RunWorkerAsync(CInt(Me.NumericUpDown1.Value))
        End Sub
        'This method is executed in a worker thread.
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
                                         ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Dim worker As backgroundWorker = DirectCast(sender, backgroundWorker)
            Dim iterationCount As Integer = 0
    
            If TypeOf e.Argument Is Integer Then
                iterationCount = CInt(e.Argument)
            End If
    
            For i As Integer = 1 To iterationCount Step 1
                'Do something here.
            Next i
        End Sub
    
        'This method is executed in the UI thread.
        Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
                                                            ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
            Me.ProgressBar1.Value = e.ProgressPercentage
            Me.Label1.Text = TryCast(e.UserState, String)
    
        End Sub
    
        'This method is executed in the UI thread.
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
                                                               ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            Me.Label1.Text = "Operation complete"
        End Sub
    End Class
    Thanks in advance for any help!
    The BackgroundWorker class is a member of the System.ComponentModel namespace. If you haven't imported that namespace then you'll need to qualify the class name with the namespace, as for all the 'e' parameters in the event handlers.

  36. #36
    New Member
    Join Date
    Jun 2009
    Posts
    9

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by jmcilhinney View Post
    The BackgroundWorker class is a member of the System.ComponentModel namespace. If you haven't imported that namespace then you'll need to qualify the class name with the namespace, as for all the 'e' parameters in the event handlers.
    It's working now, thanks for the help!

  37. #37
    Fanatic Member Lasering's Avatar
    Join Date
    May 2006
    Location
    Lisboa
    Posts
    559

    Re: Using the BackgroundWorker Component

    Excellent post! It has helped me a lot!! Keep up the always great work jmcilhinney!
    Controls: XPCC|Quantum
    Windows API'sLINQ to XML SamplesRegex Tutorial

    Albert Einstein:
    "Imagination is more important than knowledge."
    "Everything should be made as simple as possible, but not simpler."
    "Great spirits have often encountered violent opposition from weak minds."

  38. #38
    Hyperactive Member
    Join Date
    Nov 2008
    Location
    USA
    Posts
    257

    Re: Using the BackgroundWorker Component

    I have tried to adapt your code to a console application and it seems to working as far as running the background worker, and I do have the ProgressChanged and RunWorkerCompleted functions to monitor it, the process ends after one cycle of its do work process.
    Code:
      
    While Not response.Equals("3")
                    Try
    
                        Console.Write("Enter choice: ")
                        response = Console.ReadLine()
                        Console.WriteLine()
                        If response.Equals("1") Then
                            Console.WriteLine("Thread 1 doing work" & vbNewLine)
                            engine.LoadFile()
                            'tm.SetApartmentState(ApartmentState.STA)
                            'tm.Start()
    
                            response = String.Empty
                        ElseIf response.Equals("2") Then
                            Console.WriteLine("Starting a second Thread")
                            'ts.Start()
                            report()
                            response = String.Empty
                        End If
    
                        'ts.Join()
                        'tm.Join()
    
                    Catch ex As Exception
    as you can see the commented parts was an attempt to try threads; wasnt successful.

    Here is where the background worker is being called from, sub engine.loadfile()

    Code:
    bgw.WorkerReportsProgress = True
    
           AddHandler bgw.DoWork, New DoWorkEventHandler(AddressOf Search)
           bgw.RunWorkerAsync()
          AddHandler bgw.ProgressChanged, New ProgressChangedEventHandler(AddressOf ProgressChanged)
          AddHandler bgw.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf RunWorkerComplete)
    the actual do work process

    Code:
    Private Sub Search(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    ...
                  BloObj.Main(connectionString, userAgent, fileName, clientName, clientProj)
                    Dim i As Integer
                    For i = 1 To 100
                        CType(sender, BackgroundWorker).ReportProgress(i)
                        Thread.Sleep(100)
                    Next
                    Console.ResetColor()
                    Console.Write("Search Complete, Do you wish to generate queries, y or n? ")
    reply = Console.ReadLine()
                    If reply = "y" Then
                        report()
                    ElseIf reply = "n" Then
                        Console.Clear()
                        main()
                    End If
                Catch ex As Exception
                    errormessage = ex.Message
    
                End Try
    Any ideas appreciated.
    -- Please rate me if I am helpful --

  39. #39

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,302

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by cengineer View Post
    I have tried to adapt your code to a console application and it seems to working as far as running the background worker, and I do have the ProgressChanged and RunWorkerCompleted functions to monitor it, the process ends after one cycle of its do work process.
    Code:
      
    While Not response.Equals("3")
                    Try
    
                        Console.Write("Enter choice: ")
                        response = Console.ReadLine()
                        Console.WriteLine()
                        If response.Equals("1") Then
                            Console.WriteLine("Thread 1 doing work" & vbNewLine)
                            engine.LoadFile()
                            'tm.SetApartmentState(ApartmentState.STA)
                            'tm.Start()
    
                            response = String.Empty
                        ElseIf response.Equals("2") Then
                            Console.WriteLine("Starting a second Thread")
                            'ts.Start()
                            report()
                            response = String.Empty
                        End If
    
                        'ts.Join()
                        'tm.Join()
    
                    Catch ex As Exception
    as you can see the commented parts was an attempt to try threads; wasnt successful.

    Here is where the background worker is being called from, sub engine.loadfile()

    Code:
    bgw.WorkerReportsProgress = True
    
           AddHandler bgw.DoWork, New DoWorkEventHandler(AddressOf Search)
           bgw.RunWorkerAsync()
          AddHandler bgw.ProgressChanged, New ProgressChangedEventHandler(AddressOf ProgressChanged)
          AddHandler bgw.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf RunWorkerComplete)
    the actual do work process

    Code:
    Private Sub Search(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    ...
                  BloObj.Main(connectionString, userAgent, fileName, clientName, clientProj)
                    Dim i As Integer
                    For i = 1 To 100
                        CType(sender, BackgroundWorker).ReportProgress(i)
                        Thread.Sleep(100)
                    Next
                    Console.ResetColor()
                    Console.Write("Search Complete, Do you wish to generate queries, y or n? ")
    reply = Console.ReadLine()
                    If reply = "y" Then
                        report()
                    ElseIf reply = "n" Then
                        Console.Clear()
                        main()
                    End If
                Catch ex As Exception
                    errormessage = ex.Message
    
                End Try
    Any ideas appreciated.
    Your code doesn't really make sense to me. I don't see why you have a BGW at all. You seem to be prompting the user for data from the background thread. Usually the point of background threads is to perform time-consuming processing in the background so that the user can still interact with the application in the foreground. What's the point of having multiple threads in your case?

  40. #40
    Hyperactive Member
    Join Date
    Nov 2008
    Location
    USA
    Posts
    257

    Re: Using the BackgroundWorker Component

    Sorry about the confusion... I need to implement threads on the menu options I have and the one process is a long search crawling process which after it starts does not involve any user interaction.
    I figured the background process would work well here.

    Code:
    Console.ResetColor()
                Console.Write("Begin Search -- Discovery Search, y or n? ")
                response1 = Console.ReadLine()
                If response1 = "y" Then
                    Console.ForegroundColor = ConsoleColor.White
                    Console.WriteLine()
    
                    Console.Write("Enter client name: ")
                    clientName = Console.ReadLine()
                    Console.WriteLine()
                    Console.Write("Enter client project: ")
                    clientProj = Console.ReadLine()
                    ' This is where I would like to call the background process
                    bgw.WorkerReportsProgress = True
    
                    AddHandler bgw.DoWork, New DoWorkEventHandler(AddressOf Search)
                    bgw.RunWorkerAsync()
                    AddHandler bgw.ProgressChanged, New ProgressChangedEventHandler(AddressOf ProgressChanged)
                    AddHandler bgw.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf RunWorkerComplete)
                    'bgw.ReportProgress(80)
                    ' I was unable to make sure the process returned to the menu options so I put in a return here to the main where its called from
                    Return
                    'Search()
    The actual search process only contains a user response after it supposed to complete. The background process is not only one function but involves calling other classes and functions to the crawling process. As i mentioned before I tried using threads but found that it did not run in the background as I intended. Also the background process is stopping before completion without any indication. I placed breakpoints to catch the possible errors but the app just ends after a while.
    -- Please rate me if I am helpful --

Page 1 of 3 123 LastLast

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