Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  .NET Framework  »  Framework 2.0  »  Multithreading The Easy Way: The BackgroundWorker  »  Task Complete - RunWorkerCompleted or Cancelled
 »  Home  »  .NET Framework  »  Framework 3.0  »  Multithreading The Easy Way: The BackgroundWorker  »  Task Complete - RunWorkerCompleted or Cancelled
 »  Home  »  .NET Intermediate  »  Multithreading The Easy Way: The BackgroundWorker  »  Task Complete - RunWorkerCompleted or Cancelled
 »  Home  »  Visual Studio 2005  »  Multithreading The Easy Way: The BackgroundWorker  »  Task Complete - RunWorkerCompleted or Cancelled
 »  Home  »  Visual Studio 2008  »  Multithreading The Easy Way: The BackgroundWorker  »  Task Complete - RunWorkerCompleted or Cancelled
 »  Home  »  Windows Development  »  Visual Basic 2005  »  Multithreading The Easy Way: The BackgroundWorker  »  Task Complete - RunWorkerCompleted or Cancelled
 »  Home  »  Windows Development  »  Windows Presentation Foundation  »  Multithreading The Easy Way: The BackgroundWorker  »  Task Complete - RunWorkerCompleted or Cancelled
Multithreading The Easy Way: The BackgroundWorker
by Ged Mead | Published  06/01/2008 | Framework 2.0 Framework 3.0 .NET Intermediate Visual Studio 2005 Visual Studio 2008 Visual Basic 2005 Windows Presentation Foundation | Rating:
Task Complete - RunWorkerCompleted or Cancelled

   Although in our simple example, it is obvious when the task has been completed you may well have scenarios where this isn't so.  For example you may prefer in some cases to minimize the progress form and only have it appear back at its default size once the task is complete.

  The place for the code to do this kind of task is in the RunWorkerCompleted event.  Unlike the ProgressChanged event, the BGW will fire its RunWorkerCompleted event once it effectively runs out of task - in our example, therefore, once it has enumerated through every folder and file in its task.

  With the ListBox, one thing you could do would be to reset the selected file back up to the first one in the list.  (Again in the demo solution I have made changes to a progress label - making it totally clear to the user that the task has finished).

Code Copy
    Private Sub bWkrFileCheck_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bWkrFileCheck.RunWorkerCompleted
        If fp.ListBox1.Items.Count > 0 Then fp.ListBox1.SelectedIndex = 0
    End Sub

 

Note the If Then statement which ensures that the app won't crash if the search had resulted in no files being found (and therefore no first item in the ListBox to select).

Task Cancellation

   There is of course another situation which may cause  the task to end and that is where the user decides they want to cancel it.  

   When you are testing this kind of project in the Visual Studio IDE you can end it by closing down the startup form or hitting the Stop Debugging button.  However it might not be so good to force your users to close down the whole application if they only want to halt the background task!  Happily there is another property which makes this very easy - the ReadOnly CancellationPending property  - and a cancellation method of the BackgroundWorker - CancelAsync.   In combination, these will enable you to offer users a get-out clause.

  Add a second button to your project and name it btnStop.  Insert a call to the CancelAsync method of the BGW:

Code Copy
   Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
        bWkrFileCheck.CancelAsync()
    End Sub

 

  All that remains now is some way of actually terminating the running background process.  In our example, exiting the FileFinder sub will do nicely:

Code Copy
Sub FileFinder(ByVal dir As String)
        Try
            If bWkrFileCheck.CancellationPending Then Exit Sub
            ' Display all files in a directory that match file type
            For Each fname As String In Directory.GetFiles(dir)

                If fname.EndsWith("txt") Then
                    '  pass back progress message
                    bWkrFileCheck.ReportProgress(0, fname)
                End If
            Next

            ' A recursive call for all the subdirectories in this directory.
            For Each subdir As String In Directory.GetDirectories(dir)
                FileFinder(subdir)
            Next

        Catch ex As Exception
            MessageBox.Show(ex.Message.ToString)

        End Try
    End Sub

 

  Try running the project and hit the Stop button at some point in the run.  This will gracefully terminate the task the very next time the FileFinder procedure runs the If CancellationPending check.  

 

 

Comments    Submit Comment

Comment #1  (Posted by an unknown user on 06/04/2008)
Rating
Very clear and easy to follow. AND the sample Worked!!!!
 
Comment #2  (Posted by RAB on 06/12/2008)
Rating
Can we use teh Backgroundworker component without a form? Can it be instantiated in a module?
 
Comment #3  (Posted by Ged Mead on 06/20/2008)
Rating
Yes you can do that. However as there is no toolbox available for a Module you have to create the bgw in code. To do this you use Dim bgw as New System.ComponentModel.BackgroundWorker.
You will of course also need to set the properties and add handlers in code.
If you need more info on this question please post a question in the vbcity VB.NET forums (where it's easier for me to post code samples) :-}
 
Comment #4  (Posted by an unknown user on 07/30/2008)
Rating
Thank a lot XTab
 
Comment #5  (Posted by an unknown user on 08/08/2008)
Rating
Great step-by-step with in-line code. Ged obviously put alot of time in this well written article.
More please !
 
Comment #6  (Posted by an unknown user on 08/13/2008)
Rating
I try to read everything you publish. Great stuff.
 
Comment #7  (Posted by an unknown user on 08/18/2008)
Rating
Excellent and simple to use.
 
Comment #8  (Posted by an unknown user on 09/06/2008)
Rating
practical, readable
 
Comment #9  (Posted by an unknown user on 09/29/2008)
Rating
This guide was one of the best guides I've read!

You just helped me understand something I origionally had no clue about. Thanks!
 
Comment #10  (Posted by Matt Higginbotham on 10/31/2008)
Rating
Thanks Ged! What a great article.. This helped me a bunch with some long database queries that i have.

Keep Em' Coming
 
Comment #11  (Posted by an unknown user on 11/03/2008)
Rating
Very good except the cancelation did not work correctly, although it cancelled the task if I cancelled it and then re-ran I got "Operation has already had OperationCanceled called on it". I need to reset the canelled property at finish but, its read only any ideas?
 
Sponsored Links