使用BLToolkit时,我发现一个有趣的事实——methodInfo.Invoke不总是捕获调用方法中的异常。
例如,在静态构造函数中模拟异常,并通过反射调用该方法。
问题在于TestComponent继承自Component并覆盖了Dispose方法。因此,在这个示例中将会有两个消息——一个“已处理”和一个“未处理”,似乎组件在Reflection的低层级上有不同的处理方式。
如果我们注释掉Dispose(bool disposing)方法,我们将只收到“已处理”消息。
有人能解释一下为什么会发生这种情况并提出解决方案吗?在BLToolkit内部使用try-catch不能作为答案——我不是他们团队的成员 :)
例如,在静态构造函数中模拟异常,并通过反射调用该方法。
问题在于TestComponent继承自Component并覆盖了Dispose方法。因此,在这个示例中将会有两个消息——一个“已处理”和一个“未处理”,似乎组件在Reflection的低层级上有不同的处理方式。
如果我们注释掉Dispose(bool disposing)方法,我们将只收到“已处理”消息。
有人能解释一下为什么会发生这种情况并提出解决方案吗?在BLToolkit内部使用try-catch不能作为答案——我不是他们团队的成员 :)
class Program
{
static void Main()
{
AppDomain.CurrentDomain.UnhandledException +=
(sender, eventArgs) => Console.WriteLine("unHandled " + eventArgs.ExceptionObject.GetType().FullName);
try
{
try
{
var instance = Activator.CreateInstance(typeof(ComponentExecutor));
MethodInfo mi = typeof(ComponentExecutor).GetMethod("Do");
BindingFlags bf = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly |
BindingFlags.InvokeMethod;
mi.Invoke(instance, bf, null, new object[0], CultureInfo.InvariantCulture);
}
catch (TargetInvocationException tarEx)
{
throw tarEx.InnerException;
}
}
catch (Exception ex)
{
Console.WriteLine("Handled " + ex.GetType().FullName);
}
}
class ComponentExecutor
{
public void Do()
{
new TestComponent().Do();
}
}
class TestComponent : Component
{
static TestComponent()
{
throw new NullReferenceException();
}
[MethodImpl(MethodImplOptions.NoInlining)]
public void Do()
{
Console.WriteLine("Doing");
}
protected override void Dispose(bool disposing)
{
Console.WriteLine("Disposing");
base.Dispose(disposing);
}
}
}