Why exception is not caught in BackgroundWorker DoWork routine?
-
Either I throw exception or induce it naturally in DoWork it is not caught and control is not passed to worker completion routine instead getting that exception which I catch in Program.cs file
Type: System.Reflection.TargetInvocationException
Source: mscorlib
Message: Exception has been thrown by the target of an invocation.
Target Site: System.Object _InvokeMethodFast(System.IRuntimeMethodInfo, System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeType)
Module Name: mscorlib.dll
Module Path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
Stack:
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) -
Either I throw exception or induce it naturally in DoWork it is not caught and control is not passed to worker completion routine instead getting that exception which I catch in Program.cs file
Type: System.Reflection.TargetInvocationException
Source: mscorlib
Message: Exception has been thrown by the target of an invocation.
Target Site: System.Object _InvokeMethodFast(System.IRuntimeMethodInfo, System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeType)
Module Name: mscorlib.dll
Module Path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
Stack:
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)That's normal behavior. The exception doesn't get thrown across the thread boundary. Of course, a background worker can return any object as a result, so when I use them (And I do, extensively), I do it like this:
private void SomethingBackground(object sender, DoWorkEventArgs e)
{
try
{
// ...
}
catch (SomethingSomethingException ex)
{
// normal exception handling
}
catch (Exception ex)
{
e.Result = ex;
}
}// And in the caller:
if (e.Result is Exception)
throw (Exception)e.Result; // Or you could handle it some other way here
else
{
// Normal result processing
}If you're doing this a lot, you could even make a generic wrapper to centralize the code... Plenty of options. Nevermind... Not enough caffeine...
Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels) -
That's normal behavior. The exception doesn't get thrown across the thread boundary. Of course, a background worker can return any object as a result, so when I use them (And I do, extensively), I do it like this:
private void SomethingBackground(object sender, DoWorkEventArgs e)
{
try
{
// ...
}
catch (SomethingSomethingException ex)
{
// normal exception handling
}
catch (Exception ex)
{
e.Result = ex;
}
}// And in the caller:
if (e.Result is Exception)
throw (Exception)e.Result; // Or you could handle it some other way here
else
{
// Normal result processing
}If you're doing this a lot, you could even make a generic wrapper to centralize the code... Plenty of options. Nevermind... Not enough caffeine...
Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels)Will you argue with MSDN? http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx[^]
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. If you have more than one BackgroundWorker, you should not reference any of them directly, as this would couple your DoWork event handler to a specific instance of BackgroundWorker. Instead, you should access your BackgroundWorker by casting the sender parameter in your DoWork event handler
Чесноков
-
That's normal behavior. The exception doesn't get thrown across the thread boundary. Of course, a background worker can return any object as a result, so when I use them (And I do, extensively), I do it like this:
private void SomethingBackground(object sender, DoWorkEventArgs e)
{
try
{
// ...
}
catch (SomethingSomethingException ex)
{
// normal exception handling
}
catch (Exception ex)
{
e.Result = ex;
}
}// And in the caller:
if (e.Result is Exception)
throw (Exception)e.Result; // Or you could handle it some other way here
else
{
// Normal result processing
}If you're doing this a lot, you could even make a generic wrapper to centralize the code... Plenty of options. Nevermind... Not enough caffeine...
Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels)Hi Ian, you've lost me here, in two ways: 1. I don't understand what "in the caller" would mean, and how you would get that synchronized with the BGW having finisked. You might want to add a bit of code and/or explanation to make that clear. 2. I also don't see a need to do anything special; in the RunWorkerCompleted event, the e.Error property automatically holds the Exception that caused the DoWork handler to finish prematurely. Cheers.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Please use <PRE> tags for code snippets, they improve readability.
CP Vanity has been updated to V2.3 -
Hi Ian, you've lost me here, in two ways: 1. I don't understand what "in the caller" would mean, and how you would get that synchronized with the BGW having finisked. You might want to add a bit of code and/or explanation to make that clear. 2. I also don't see a need to do anything special; in the RunWorkerCompleted event, the e.Error property automatically holds the Exception that caused the DoWork handler to finish prematurely. Cheers.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Please use <PRE> tags for code snippets, they improve readability.
CP Vanity has been updated to V2.3Yeah, this is what I get for trying to answer questions in the morning when I'm having a bad week... Heh... You're right on both counts. I abstracted all of this away months ago to run background workers with an animated progress dialog, so I can do things like:
x = Util.ProgressDialog.Show(owner, MyWorkerMethod, "Doing something") as MyResultObject;
private void MyWorkerMethod(BackgroundWorker wkr, DoWorkEventArgs e)
{
// ...
e.Result = ...
}Proud to have finally moved to the A-Ark. Which one are you in?
Author of the Guardians Saga (Sci-Fi/Fantasy novels) -
Either I throw exception or induce it naturally in DoWork it is not caught and control is not passed to worker completion routine instead getting that exception which I catch in Program.cs file
Type: System.Reflection.TargetInvocationException
Source: mscorlib
Message: Exception has been thrown by the target of an invocation.
Target Site: System.Object _InvokeMethodFast(System.IRuntimeMethodInfo, System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeType)
Module Name: mscorlib.dll
Module Path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll
Stack:
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)As you did not present any code, I assume that you are having a problem with Control.Invoke Method (Delegate) method. The exception is not thrown if you try to change some control's properties directly from inside a thread. For example:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ChangeMyText("Privet");
}private void ChangeMyText(string myText) { label1.Text = myText; }
The result will be a dead backgroundWorker. It will not say anything but die when it reaches
label1.Text = myText;
and will not throw an exception. Instead, you have to use
label1.Invoke((Action)delegate
{
label1.Text = myText;
});____________ Ulugbek