Inner exception is thrown from Control.Invoke instead of "outer" Exception, framework bug?

M

Martin

Hi,
I have an application that calls an async delegate from the UI thread.
The async operation throws an exception with an inner exception
attached. When I get the callback in my form class I call
this.Invoke(...) which throws an exception as expected. However, the
exception thrown is the inner exception! Can anyone explain this? I've
attached a complete Program.cs below that reproduces the error.

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace TestAsyncException
{
class MyForm : Form
{
public MyForm()
{
this.Load += new EventHandler(MyForm_Load);
}

void MyForm_Load(object sender, EventArgs e)
{
ManualResetEvent theEvent = new ManualResetEvent(false);

VoidMethod voidMethod = WorkerMethod;

IAsyncResult iar = voidMethod.BeginInvoke(
delegate(IAsyncResult result)
{
try
{
VoidMethod dg = (VoidMethod)result.AsyncState;

if (this.InvokeRequired)
this.Invoke(new
AsyncCallback(dg.EndInvoke), new object[] { result });
else
dg.EndInvoke(result);

}
catch (Exception exc)
{
// Displays "Got error: Original Error"!!
Trace.TraceInformation("Got error: " +
exc.Message);
}

theEvent.Set();
}, voidMethod);

// Wait until the async operation is complete
while (!theEvent.WaitOne(10, false))
Application.DoEvents();
}

delegate void VoidMethod();

void WorkerMethod()
{
try
{
ExceptionMethod();
}
catch (Exception e)
{
throw new Exception("New Error", e);
}
}

void ExceptionMethod()
{
throw new Exception("Original Error");
}

}

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new MyForm());
}
}
}
 
M

Martin

Using .Net Reflector, I found this piece of code in
Control.InvokeMarshaledCallbacks:

try
{
this.InvokeMarshaledCallback(tme);
}
catch (Exception exception)
{
tme.exception = exception.GetBaseException();
}

The question still remains though. Why us exception.GetBaseException()
instead of the exception object?
 
M

Martin

Someone from Microsoft answered this at

http://www.developermania.com/newsg...ndWorker__MyApplication_UnhandledExcepti.aspx

"Based on the winform comfirmation in the record, our analysis is
correct of
the root cause and this behavior is intended. The reason was to
prevent the
user from seeing too much of the Windows.Forms internal mechanisms.
This is
because the winform's default error dialog also leverages
Application.ThreadException to show the exception details. .Net
Winform
team trims the other exceptions information so that the default error
dialog will not display all the details to the end user.

Also, some MSFTs have sugguested to change this behavior.
However, .Net
Winform team thinks that changing the exception to throw is a
breaking
change and for this reason WinForms will keep sending the innermost
exception to the Application.ThreadException handler."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top