C#(不是ASP / MVC / WinForms) - 捕获类中的所有异常 [英] C# (not ASP/MVC/WinForms) - Catch all exceptions in a class

查看:121
本文介绍了C#(不是ASP / MVC / WinForms) - 捕获类中的所有异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一些背景信息



我在使用专有编程语言的系统中进行编程,可以在专有代码中使用专门归属的.Net类。 / p>

不幸的是,系统不会处理从.Net代码冒出来的未处理的异常,如果事实根本没有;系统崩溃,没有解释。这是烦人的,因为我们经常想处理专有系统中的异常,而不是.Net代码。系统供应商提供的解决方案是将异常重新打包成系统处理的特殊对象。



我们的.Net代码是以外观图案编写的,问题是要确保从.Net代码中冒出的每个异常都被处理,外观中的每个方法都必须包含一个try / catch块,该块重新打包可能发生的任何异常。



问题



我在这里描述了很多线程,描述了类似的场景,其中大多数是WinForms-或网络相关。因为我们的代码既不是,问题是如果有一些方法来捕获一个类中的所有异常,以便我们可以重新打包它并重新打开它们的修改版本?



显然,包含类和专有语言的.Net dll之间的界面完全无法控制。



编辑



我尝试了@VMAtm建议的 currentDomain.UnhandledException 方法,不幸的是没有用。事件处理程序没有触发,父系统保持异常,然后照常行为不当。这再次导致我进入Google,我发现这一段这里


首先要理解的是UnhandledException事件不是未处理的异常处理程序。注册该事件,与文档说明相反: - (不会导致未处理的异常被处理)(从那以后,它们将不会被处理,但是我将停止循环推理已经...)UnhandledException事件只是通知你一个异常已经没有得到处理,以防在线程或应用程序死机前尝试保存状态。



Jonathan Keljo,CLR异常PM


这太糟糕了,我喜欢有一个全局try / catch块的想法,我猜这是意味着我'在父系统中隐藏异常并不成功,因为我不知道在系统中如何实现这一点的第一件事情(坦白说,我不知道第一件事情是怎么去实现的我自己)我的假设很薄,所以如果有任何人可以以任何方式纠正我,请继续前进!



哦,我的错误进入父系统是调用目标抛出异常。,据我所知,外部的.Net异常发生的消息。如果可以读取任何东西,我不知道。



我将去@jlew建议的Castle Dynamic Proxy,但是它看起来比两个AppDomain线更难,而且吓了我一跳:)



解决方案



如果你有与我一样的问题,你应该先尝试@VMAtm建议的 currentDomain.UnhandledException 方法,因为这是因为我的父系统特别肛门,我可以通过使用Castle DynamicProxy设置来实现它的工作。



真的很容易设置。我的测试用例是封装XmlAttribute类的外观类。我必须做的第一件事是编写代理类:

  public class AttribInterceptor:IInterceptor 
{
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
}
catch(异常e)
{
//自定义异常重新包装在这里
}
}
}

然后我必须指示外观对象实际使用代理。我保留了我的旧后端字段,但是添加了以下内容:

  public class CapXmlAttribute:CapPmlNetObject 
{
private XmlAttributeBackend _xmlAttribute;

public CapXmlAttribute()
{
var generator = new ProxyGenerator();
_xmlAttribute =(XmlAttributeBackend)generator.CreateClassProxy(
typeof(XmlAttributeBackend),新的AttribInterceptor());
}
}

最后一步是设置后端的所有方法被视为 virtual 。这对我来说没有问题,但可能是别人的破产者。



DynamicProxy 真的不是很好的记录,但我从 KrzysztofKoźmic的教程 Hamilton Verissimo的代码项目

解决方案

我将看看使用类似城堡动态代理

这将允许您的类方法调用以通用的方式被拦截,这将为您提供一个放置catch的中心位置-all异常处理程序。 (也就是说,我们不清楚你的课程是如何实际实例化的,这可能会导致这种方法有问题)


Some background info

I am programming in a system that uses a proprietary programming language, with the option of using specially attributed .Net classes in the proprietary code.

Unfortunately, the system doesn't handle unhandled exceptions bubbling up from .Net code well, if fact not at all; the system crashes with no explanation. This is annoying, because we often want to handle exceptions in the proprietary system, not in .Net code. The solution offered by the vendor of the system is to repackage the exception into a special object that the system does handle.

Our .Net code is written in a façade pattern, and the problem is that to make sure every exception that bubbles up from the .Net code is handled, every method in the facade must include a try/catch block that repackages any exceptions that may occur.

The question

I've read a lot of threads here describing similar scenarios, most of them WinForms- or web-related. Because our code is neither, the question is if there is some way to catch all exceptions in a class, so that we can repackage it and rethrow a modified version of them?

Obviously, the interface between the .Net dll's containing the classes and the proprietary language is completely beyond our control.

Edit

I tried the currentDomain.UnhandledException method suggested by @VMAtm, unfortunately to no avail. The event handler didn't fire, and the parent system got hold of the exception and then misbehaved as usual. That led me onto Google once more, and I found this paragraph here:

The first thing to understand is that the UnhandledException event is not an unhandled exception "handler". Registering for the event, contrary to what the documentation says :-(, does not cause unhandled exceptions to be handled. (Since then they wouldn't be unhandled, but I'll stop with the circular reasoning already...) The UnhandledException event simply notifies you that an exception has gone unhandled, in case you want to try to save state before your thread or application dies.

Jonathan Keljo, CLR Exceptions PM

That was too bad, I liked the idea of having a "global" try/catch block. What I guess it means is that I'm not successful in hiding the exception from the parent system. Since I don't know the first thing about how this is implemented in that system (and frankly, I don't know the first thing about how I'd go on to implement it myself) I'm on really thin ice with my assumptions, so if anyone can correct me in any way, please go ahead!

Ohh, the error I'm getting in the parent system is Exception has been thrown by the target of an invocation., which is as far as I know the message from the outer .Net exception occurring. If it's possible to read anything out of that, I don't know.

I'll have a go at the Castle Dynamic Proxy suggested by @jlew as well, but it looked a lot harder than the two AppDomain lines and scared me quite a bit :)

Solution

If you are having the same problem as I had, you should try the currentDomain.UnhandledException method suggested by @VMAtm first, because it's because of my parent system being especially anal it didn't work.

I got it working by using the Castle DynamicProxy setup. It was really very easy to set up. My test case was a façade class encapsulating the XmlAttribute class. The first thing I had to do was to write the proxy class:

public class AttribInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();
        }
        catch (Exception e)
        {
            // Custom exception repackaging here
        }
    }
}

Then I had to instruct the façade object to actually use the proxy. I kept my old backend field, but added the following to the c'tor:

public class CapXmlAttribute : CapPmlNetObject
{
    private XmlAttributeBackend _xmlAttribute;

    public CapXmlAttribute()
    {
        var generator = new ProxyGenerator();
        _xmlAttribute = (XmlAttributeBackend) generator.CreateClassProxy(
            typeof (XmlAttributeBackend), new AttribInterceptor());
    }
}

The last step was setting all methods in the backend that is exposed to the façade as virtual. This was no problem for me, but might be a dealbreaker for others.

DynamicProxy really isn't that good documented, but I learned a lot from Krzysztof Koźmic's tutorial and Hamilton Verissimo's codeproject.

解决方案

I would take a look at using something like Castle Dynamic Proxy.
This will allow your class method calls to be intercepted in a generic way, which would give you a central place to put a "catch-all" exception handler. (That said, it's unclear to me how your classes are actually instantiated, which might make this approach problematic)

这篇关于C#(不是ASP / MVC / WinForms) - 捕获类中的所有异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆