BackgroundWorker unhandled error
- Hi, I'm having trouble with BackgroundWorker. I have some code in the BackgroundWorker_DoWork() event that can raise an error. According to the BackgroundWorker documentation, errors raised in BackgroundWorker_DoWork() should be captured by BackgroundWorker_RunWorkerCompleted() event and appear in the events args as e.Error . But when I try this, every time my code raises an error, the debugger says its an unhandled exception. I've tried the MSDN example and again the debugger arcs up. I've even tried the solution from a C# post which was to make sure that checking of e.Error was the first line in the BackgroundWorker_RunWorkerCompleted() event - still no joy... Any suggestions?
Answers
The plot thickens... I was going through that code again just before, the apparently unhandled exception was thrown and just out of habit I pressed 'Play' and vwola!! it went to the BackgroundWorker_RunWorkerCompleted() event where the exception appeared at e.Error!!! Taking that logic a step further I ran my program without debugging and sure enough the error was handled by my error handling code in BackgroundWorker_RunWorkerCompleted(). So, I think the conundrum might be solved, but I'm not sure I like the outcome. Surely there is an option somewhere to suppress these sort of errors whilst debugging... Unless of course it is a bug, but then you would think it would throw an unhandled error when published.
Hi,
no bugs here. Decorate your DoWork handler with System.Diagnostics.DebuggerNonUserCodeAttribute().
This keeps the debugger away from the handler's code, and makes behave in debug mode as it would in runtime.
All Replies
You're right that the BackgroundWorker should be catching the exception and returning it. So it's most likely a bug in the way you're setting up the BackgroundWorker. Can you post the code where you setup and start the background worker?
Also when the debugger says that an unhandled exception occurred, on what thread does it say this happened? If you're not sure break and post the stack of the current thread.
- Hi Jared, thanks for your prompt response. Re: code, I have attached the code below, but I would have thought it just as easy to try the MSDN example I referenced in the first post, because I would have expected them to have it right! Anyway, here it is:
Dim LoggingIn As Boolean
Private Sub cmdLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLogin.Click
If Not LoggingIn Then
cmdLogin.Text = "Cancel"
LoggingIn = True
wrkBackground.RunWorkerAsync("Login")
Else 'Cancel
wrkBackground.CancelAsync()
End If
End Sub
Private Sub wrkBackground_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles wrkBackground.DoWork
' Do not access the form's BackgroundWorker reference directly.
' Instead, use the reference provided by the sender parameter.
Dim bw As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
Select Case e.Argument.ToString
Case "Login"
Login(bw) 'Method that handles the downloading of info
End Select
If wrkBackground.CancellationPending Then
e.Cancel = True
End If
End Sub
Private Sub wrkBackground_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles wrkBackground.RunWorkerCompleted
If e.Error IsNot Nothing Then
MsgBox("Received the following error:" & vbCrLf & _
e.Error.Message, MsgBoxStyle.Exclamation)
ElseIf e.Cancelled Then
cmdLogin.Text = "Login"
LoggingIn = False
Else 'Success!
cmdLogin.Text = "Login"
LoggingIn = False
DoStuff()
End If
End Sub
Hmmm, you make a good point regards which thread the error is occurring on. I remember when I was using a WebClient asynchronously, if an unhandled error was thrown by it, it would say "Target of invocation" or something, where as this is showing the actual error, suggesting its on the same thread. And I thought I might have had the answer for second because the error that I'm throwing is coming from a class instance that I have initialised outside of the BackgroundWorker thread but then I tried throwing an error in the wrkBackground_DoWork() event, and it still didn't capture it!
Private Sub wrkBackground_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles wrkBackground.DoWork
Throw New Exception("Why wont you work???")
End Sub
This shows an unhandled error window with stack trace:
System.Exception was unhandled by user code
Message="Why wont you work???"
Source="MyProgram"
StackTrace:
at MyProgram.frmMain.wrkBackground_DoWork(Object sender, DoWorkEventArgs e) in C:\Documents and Settings\Me\My Documents\Visual Studio 2005\Projects\MyProgram.\frmMain.vb:line 261
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
As I said though, you would think that the MSDN example would work and I've basically followed their structure. So maybe there is some sort of option somewhere for BackgroundWorker exceptions to be thrown rather than captured or something. Anyway, I look foward to your reply. Thanks! The plot thickens... I was going through that code again just before, the apparently unhandled exception was thrown and just out of habit I pressed 'Play' and vwola!! it went to the BackgroundWorker_RunWorkerCompleted() event where the exception appeared at e.Error!!! Taking that logic a step further I ran my program without debugging and sure enough the error was handled by my error handling code in BackgroundWorker_RunWorkerCompleted(). So, I think the conundrum might be solved, but I'm not sure I like the outcome. Surely there is an option somewhere to suppress these sort of errors whilst debugging... Unless of course it is a bug, but then you would think it would throw an unhandled error when published.
Hi,
no bugs here. Decorate your DoWork handler with System.Diagnostics.DebuggerNonUserCodeAttribute().
This keeps the debugger away from the handler's code, and makes behave in debug mode as it would in runtime.
- Ah brilliant! Thanks. I found though that I had to set that attribute to the lowest level methods that could throw exceptions rather than just the DoWork method. Is there an all-encompassing attribute that I can set just for the DoWork method? Thanks once again, this is just what I was after!
Cheers,
Hoopla People interested in this topic my find this blog post about the BackgroundWorker useful:
http://www.developerdotstar.com/community/node/671
Best,
Dan


