C# 如何确保无论何时何地发生异常,都会执行某些预期操作?
我正在对现有代码进行一些增强。现在,无论何时何地发生异常,我都要记录一条消息 我可以在catch/finally块中添加该消息,但是有数百个catch块 是否有人能提出更好的方法,以便在程序集中代码的任何部分出现异常时记录消息?当然,您有最后一次机会使用异常处理程序 ASP.NET在HttpApplication中有它,并带有错误事件(如果您不使用HTTP模块,大多数情况下在全局ASAX中) WPF和Silverlight在应用程序中具有相同的功能 Windows窗体可以使用AppDomain.UnhandledException事件C# 如何确保无论何时何地发生异常,都会执行某些预期操作?,c#,exception-handling,C#,Exception Handling,我正在对现有代码进行一些增强。现在,无论何时何地发生异常,我都要记录一条消息 我可以在catch/finally块中添加该消息,但是有数百个catch块 是否有人能提出更好的方法,以便在程序集中代码的任何部分出现异常时记录消息?当然,您有最后一次机会使用异常处理程序 ASP.NET在HttpApplication中有它,并带有错误事件(如果您不使用HTTP模块,大多数情况下在全局ASAX中) WPF和Silverlight在应用程序中具有相同的功能 Windows窗体可以使用AppDomain.
米卡·雅各比是对的,这是一个糟糕的答案。很抱歉。当您需要处理遗留代码时,这是一个有趣的问题。
如果您真的不想更改捕获块,那么我可以建议一种解决方法:
您可以选择编写一个
LoggedExceptionInterface
或其他什么,并在其中实现一个LogEvent
,然后审核所有代码扫描以查找已处理的异常类型,并通过向它们添加接口来重新防护它们。例如,您可以将
IOException
替换为LoggedIOException
,后者继承第一个,在顶部实现LoggedExceptionInterface
。当然,这可能比单独更换挡块更重;您可以选择。第二步: 使用Postsharp的AOP是一种很好的方法 我在许多项目中使用过 您可以定义一个属性,该属性继承自PostSharp API的基础API,该API允许您截取放置自定义属性的基础API的任何方法调用 如果您将该属性放在任何方法中,您将能够尝试/捕获任何方法体,并最终控制异常并记录它们 您可以使用Castle Dynamic Proxy实现相同的目标,但这是一个运行时解决方案,因为您可以使用拦截器创建代理类,并使用工厂实例化类。显然,这将消耗更多的资源 Postsharp执行IL编织,这意味着您的拦截器将在编译时注入到实际代码中,因此,您不会失去运行时性能
总之,您可以创建一个“LogAttribute”,并将其放在任何您想要记录的方法中,或者在发生异常时执行操作。不幸的是,您必须以任何方式修改该块。或者注释它们并使用AppDomain.CurrentDomain.UnhandledException+=(TopLevelErrorHandler);Application.ThreadException+=Application\u ThreadException;当捕获所有异常导致随机失败时,需要真正强大的日志记录确实是不可避免的。不过,这还不止于此,您还需要开发工具来修复由此导致的数据损坏。只需删除所有这些try/catch语句,即可避免所有这些情况。此建议不起作用。他想要的是在现有的try/catch块中添加一些东西,这就是我的做法。这将无法获得已处理的异常。@Michael:那么如何使用AppDomain.UnhandledException绕过已处理的异常?谢谢。这似乎是一个很好的解决方案,因为在将来,我也不会期望其他开发人员每次都记住在每个catch块结束时做一些明确的操作!不要忘记向上投票(和/或在满意的情况下标记为已回答);-)考虑到Mathias建议的AOP可能是一个更干净/更花哨的选择(虽然有点重,也不那么简单)IL编织的神奇之处在于AOP变得轻巧,因为它是在编译时和幕后进行的,我真的很喜欢这种方法(你肯定注意到了,哈哈)+1:非常好的选择。我想过这个,但我还没有在.Net中真正使用AOP。虽然它有一定的开发成本,但我不知道提问者是否愿意承担。事实上,Postsharp有一个社区版,所以他应该没有使用它的成本。我相信Postsharp有很好的文档记录,而且非常容易使用,不是吗?