一些背景信息
我是在一个使用专有编程语言的系统中编程,可以选择在专有代码中使用特别属性化的.Net类。
不幸的是,如果事实并非如此,系统无法很好地处理从.Net代码中冒出来的未处理异常;系统崩溃,没有任何解释。这很烦人,因为我们通常希望在专有系统中处理异常,而不是在.Net代码中。系统供应商提供的解决方案是将异常重新打包到系统处理的特殊对象中。
我们的.Net代码是以外观模式编写的,问题是,为了确保处理从.Net代码中出现的每个异常,外观中的每个方法都必须包括一个try/catch块,该块重新打包可能发生的任何异常。
问题是
我在这里读过很多描述类似场景的线程,其中大多数都是与WinForms或web相关的。因为我们的代码都不是,所以问题是是否有办法捕获类中的所有异常,这样我们就可以重新打包它并重新抛出它们的修改版本?
显然,包含类和专有语言的.Net dll之间的接口完全超出了我们的控制范围。
编辑
我尝试了@VMAtm建议的currentDomain.UnhandledException
方法,但不幸的是没有效果。事件处理程序没有触发,父系统控制了异常,然后就像往常一样不正常。这使我再次进入Google,我发现了这段这里
首先要理解的是,UnhandledException事件不是一个未处理的异常“处理程序”。注册事件,与文档所述相反:-(不会导致处理未处理的异常。(从那时起,他们将不会被忽视,但我将停止循环推理.)UnhandledException事件只是通知您一个异常未被处理,以防您想要在线程或应用程序死前保存状态。 Jonathan,CLR异常PM
那太糟糕了,我喜欢“全局”的尝试/捕捉块的想法。我猜这意味着我没有成功地向父系统隐藏异常。因为我不知道这是如何在那个系统中实现的第一件事(坦白地说,我也不知道第一件事情是如何自己实现的),所以我的假设非常有限,所以如果有人可以在任何方面纠正我,请继续!
哦,我在父系统中遇到的错误是Exception has been thrown by the target of an invocation.
,据我所知,这是来自外部.Net异常的消息。如果有可能的话,我不知道。
我也将使用@jlew建议的,但是它看起来比两个AppDomain行要难得多,我非常害怕:)
解决方案
如果您遇到了与我相同的问题,那么您应该首先尝试@VMAtm建议的currentDomain.UnhandledException
方法,因为这是因为我的父系统特别糟糕--它没有工作。
我通过使用城堡DynamicProxy设置实现了它的工作。建立起来真的很容易。我的测试用例是封装XmlAttribute类的fa类。我要做的第一件事是编写代理类:
public class AttribInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
}
catch (Exception e)
{
// Custom exception repackaging here
}
}
}
然后,我必须指示fa对象实际使用代理。我保留了我以前的后端字段,但在C‘to中添加了以下内容:
public class CapXmlAttribute : CapPmlNetObject
{
private XmlAttributeBackend _xmlAttribute;
public CapXmlAttribute()
{
var generator = new ProxyGenerator();
_xmlAttribute = (XmlAttributeBackend) generator.CreateClassProxy(
typeof (XmlAttributeBackend), new AttribInterceptor());
}
}
最后一步是将暴露在外观中的后端中的所有方法设置为virtual
。这对我来说没什么问题,但对其他人来说可能是个大麻烦。
DynamicProxy确实不是很好的文档,但是我从Koź麦克风教程和Hamilton Verissimo码工程那里学到了很多。
发布于 2011-07-07 05:23:49
我想看看如何使用类似于城堡动态代理的东西。
这将允许您的类方法调用以一般方式被截获,这将为您提供一个放置“所有捕获”异常处理程序的中心位置。(尽管如此,我不清楚您的类是如何实例化的,这可能会使这种方法成为问题)
发布于 2011-07-07 05:30:09
正如我所理解的,您需要捕获并重新抛出未处理的异常,对吗?可以为AppDomain.UnhandledException事件添加处理程序。
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
// handle exception here, you can easily package exceptions there.
}
更新:
我在AppDomain
类中发现了另一个事件,AppDomain.FirstChanceException事件
在运行库搜索应用程序域中的异常处理程序之前,在托管代码中抛出异常时发生。
也许这可以解决您的问题-这个事件发生在之前,在catch
块中的任何代码。
发布于 2011-07-07 05:38:47
除了VMAtm的文章之外,还可以为ThreadExceptions设置事件处理程序
https://stackoverflow.com/questions/6611215
复制相似问题