BackgroundWorker

This was introduced in .NET 2.0
The BackgroundWorker class provides a built-in wrapper for a worker thread.
Communication between the main thread and the worker thread is asyncronous.
The BackgroundWorker class allow you to have a responsive UI while you retrieve your data.


Properties 
WorkerSupportsCancellationThis property
WorkerReportsProgressThis property
Methods 
RunWorkerAsyncThis methods starts the background worker.
CancelAsyncThis method
ReportProgressThis method can be called from within the DoWork subroutine as a way of reporting progress directly to your application.
Events 
DoWorkThis event
ProgressChangedThis event fires as a consequence of calling the ReportProgress method from inside your DoWork subroutine.
RunWorkerCompletedThis event

Creating - Design Time

Create a BackgroundWorker and listen for the events that report progress and signal when the operation has finished.
If you drag it onto a form it will appear in the Components Tray underneath the form.


Creating - Run Time

You can create a BackgroundWorker programmatically or you can drag it onto a form from the Components tab of the Toolbox.

_MyWorker = new System.ComponentModel.BackgroundWorker 
_MyWorker.WorkerSupportsCancellation
_MyWorker.WorkerReportsProgress
_MyWorker.DoWork += _MyWorker_DoWork;
_MyWorker.ProgressChanged += _MyWorker_ProgressChanged
_MyWorker.RunWorkerCompleted += _MyWorker_RunWorkerCompleted

_MyWorker.RunWorkerAsync();


DoWork Event

This event fires as a consequence of calling the RunWorkerAsync method.
This fires (on a different thread) as soon as the background worker is started.
This should not have any error handling (it should be handled in the RunWorkerCompleted).
The code inside this event cannot communicate directly with the rest of your application as it runs on a different thread.

Private Sub MyWorker_DoWork() Handles MyWorker.DoWork 
try
   {
'This must not reference any controls on the windows form
'Either use local variables or parameters

}
catch

{

  'this is necessary as the backgroundworker might have been cancelled before it completed
   If (MyWorker.CancellationPending = True) Then Exit Sub

'this is necessary when running a backgroundworker behind a windows form. The form might have been closed while the backgroundworker is still running
      If (Me.IsDisposed = False) Then
         Call ErrorMessage()
      End If
   End If

   MyWorker.ReportProgress()

}
}

Async call inside background worker ?
we can kill background worker but it doesn't kill async call ??



ReportProgress Method

Remember that the code inside your DoWork subroutine cannot communicate directly with your main application.
This method in turn fires the ProgressChanged event which is fired on your main thread.



Use the ProgressChanged event to receive notifications of progress updates

Private Sub MyWorker_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles MyWorker.ProgressChanged 

   progressBar1.Value = e.ProgressPercentage



RunWorkerCompleted Event

This event fires once the code in the DoWork subroutine has completed.
This fires on the main thread and can therefore communicate directly with your application.
This should be used to handle any exceptions (caused by the DoEvents) bnecause it is on the main thread.
This event also fires when the backgroundworker is cancelled (ie the CancelAsync method is called)

Private Sub MyWorker_RunWorkerCompleted() Handles MyWorker.RunWorkerCompleted 

   If (e.Cancelled = True) Then
      Call MessageBox("The task was cancelled.")
   End If

   If e.Error <> Null Then
      Call MessageBox("There was an error: " & CType(e.Error, Exception).ToString)
   End If
End Sub

If the operation requires a parameter, call RunWorkerAsyn with this parameter
This parameter can then be extracted from the DoWorkEventArgs argument passed to the DoWork event.



Cancelling

BackgroundWorker - cancelling an async - csharp-examples.net/cancel-asynchronous-method/


VB includes a SyncLock statement that can be used as a gatekeeper.


You can use a button to cancel the backgroundworker

Private Sub btnCancel_Click(sender As , e As EventArgs) 

   MyWorker.CancelAsync()
End Sub


Private Sub btnCancel_Click() 
   If MyWorker.WorkerSupportsCancellation = True Then
      MyWorker.CancelAsync()
   End If
End Sub

Calling the CancelAsync method will fire the RunWorkerCompleted event although this should not be used as a method of identifying if the backgroundworker has completed.
It is quite possible that the RunWorkerCompleted event is fired some time after the CancelAsync method was called
You should check the CancellationPending property to tel if the backgroundworker has been cancelled.


Marshalling / Blocking

Marshalling is the name when you switch from a secondary thread to the primary UI thread.
It is the act of calling Invoke or BeginInvoke on a from that switches the flow of execution from the secondary thread to the primary thread.
Invoke - This is a blocking call
BeginInvoke - This is not a blocking call
Non blocking calls are the preferred method.



SS - cross thread operation not valid - accessed from a thread other than the thread it was created on.


Passing a Parameter

It is possible to pass a parameter to a background worker.



© 2020 Better Solutions Limited. All Rights Reserved. © 2020 Better Solutions Limited TopPrevNext