Unhandled exceptions in BackgroundWorker
If the operation raises an exception that your code does not handle, the BackgroundWorker
catches the exception and passes it into the RunWorkerCompleted
event handler, where it is exposed as the Error property of System.ComponentModel.RunWorkerCompletedEventArgs
. If you are running under the Visual Studio debugger, the debugger will break at the point in the DoWork event handler where the unhandled exception was raised.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx
I am fully using BackgroundWorker
over a years and really know it in deep.
Just recently, My RunWorkerCompleted
does not catch the e.Error
when I simply Throw New Exception("Test")
in DoWork
. However Unhandled Exception raised. Catch in DoWork
is not the best practice thus e.Error
got no meaning.
When I try to create new Form
with new BackgroundWorker
, e.Error
in RunWorkerCompleted
handled successfully. There should be something wrong in my complicated BackgroundWorker
.
After a few days googling and debugging, trying an error. I found this in my RunWorkerCompleted
:
- Check for
e.Error
first, thene.Cancelled
and lastlye.Result
- Do not get the
e.Result
ife.Cancelled = True
. - Do not get the
e.Result
ife.Error
is notnull
(orNothing
) **
** This is where I miss. If you trying to use e.Result
if e.Error
is not null
(or Nothing
), Unhandled Exception will thrown.
UPDATE:In the e.Result
get property .NET design it to check for e.Error
first, if got error, then they will re-throw the same exception from DoWork
. That is why we get Unhandled exception in RunWorkerCompleted
but actually the exception is come from DoWork
.
Here is the best practice to do in RunWorkerCompleted
:
If e.Error IsNot Nothing Then ' Handle the error hereElse If e.Cancelled Then ' Tell user the process canceled here Else ' Tell user the process completed ' and you can use e.Result only here. End IfEnd If
If you want an object that accessible to all DoWork, ProgressChanged and RunWorkerCompleted, use like this:
Dim ThreadInfos as Dictionary(Of BackgroundWorker, YourObjectOrStruct)
You can easily access ThreadInfos(sender).Field
anywhere you want.
By default it will be caught and stored by the BackgroundWorker. From MSDN:
If the operation raises an exception that your code does not handle, the BackgroundWorker catches the exception and passes it into the RunWorkerCompleted event handler, where it is exposed as the Error property of System.ComponentModel.RunWorkerCompletedEventArgs. If you are running under the Visual Studio debugger, the debugger will break at the point in the DoWork event handler where the unhandled exception was raised.