是否有任何事件在发生异常时被触发?

时间:2010-08-09 14:14:19

标签: c# .net

.Net框架中是否有任何事件在异常时触发。每当有异常被捕获时,我都需要记录它。因此,如果存在事件,我可以订阅它,并可以在事件处理程序中记录异常。

10 个答案:

答案 0 :(得分:6)

是的 - UnhandledException对象上有AppDomain个事件:

AppDomain.CurrentDomain.UnhandledException += YourHandler

仅供参考:你应该只使用这些处理程序作为最后的手段 - 在try catch块中捕获异常要好得多,尽管这可能并不总是可行的(例如在这种情况下)当第三方代码开始新线程时)

此外,只有当未处理异常时才会触发此事件 - 据我所知,如果不将调试器附加到进程,则无法以这种方式通知捕获的事件。

答案 1 :(得分:4)

您应该看看使用PostSharp进行面向方面编程,您可以编写一个简单的Log属性并将其应用于整个程序集。

你需要的就是这样:

[Serializable]
public class LogAttribute : OnMethodInvocationAspect
{
   public override void OnInvocation(MethodInvocationEventArgs eventArgs)
   {
      try
      {
         eventArgs.Proceed();
      }
      catch(Exception ex)
      {
         // log exception here
      }
   }
}

并将其应用于您的程序集:

[assembly: Log]
public class ...

这不是每个人的一杯茶,但我发现它是一种非常干净,整洁的方式,可以避免在我的课程中执行大量样板代码,并让我从事与项目本身更相关的功能。

更新:正如Kugel在评论中指出的那样,这将帮助您跟踪和记录在执行方法期间抛出的任何异常,但是如果您想记录方法内部的状态,那么我需要做比这更多的工作。

例如,您可能仍需要在方法中使用try / catch块,您可以使用它来捕获类感兴趣的异常,甚至可以将它们包装在自定义异常对象中,这样您就可以开始添加更多有用的信息,如错误代码等等。您的自定义异常有一个合适的机制来设置其“消息”属性,例如

public class DictionaryKeyNotValidException() : Exception
{
   public DictionaryKeyNotValidException(string key)
       : base(GetMessage(key))
   {   
   }

   public ErrorEnum ErrorCode { get { return ErrorEnum.InvalidDictionaryKey; } }

   private string GetMessage(string key)
   {
      return string.Format("ERROR {0} : Invalid dictionary key encountered {1}",
                           ErrorCode.GetHashCode(), key);
   }
}

然后在您的日志属性中,如果您使用的是Log4Net,则可以开始记录更多有用的信息:

catch (Exception ex)
{
   // log error
   log.Error(ex);

   // handle exception, rethrow, etc.
   ...
}

对不起,这会变得有点长.. ..

答案 2 :(得分:2)

除了Exception?我只是将我的日志模块调用添加到我的catch块中。

类似的东西:

catch(YourException ex)
{
  LogMyException(ex, [otherParamsYouNeed]);
  //Other Exception Handling
}

如果您想记录某些内容的状态而不管成功或失败,请使用finally{}

答案 3 :(得分:1)

在WinForms中,您有Application.ThreadException个事件,更常见的是AppDomain.CurrentDomain.UnhandledException事件。

但请注意,在记录这些异常之后,建议要做的就是关闭应用程序。它可能不再处于稳定状态。

答案 4 :(得分:1)

AppDomain类有一个UnhandledException事件,但我不认为您可以订阅任何异常被抛出。

答案 5 :(得分:0)

看看这个http://www.switchonthecode.com/tutorials/csharp-tutorial-dealing-with-unhandled-exceptions UnhandledExceptionEventHandler就是你正在寻找的这个是来自windows但是我觉得有类似的想法对于网络太多了
最诚挚的问候,
Iordan

答案 6 :(得分:0)

在ASP.NET中,可以通过处理Page_Error事件在页面级别捕获未处理的异常,或者通过处理应用程序错误事件在应用程序级别(在global.asax或IHttpModule实现中)捕获未处理的异常。这些事件不会给你实际的异常,因此你需要调用服务器来获取异常:

    Exception ex = HttpContext.Current.Server.GetLastError();

答案 7 :(得分:0)

要扩展theburningmonk给出的答案,您还可以尝试使用log4PostSharp。这是使用PostSharp插入与log4net日志记录框架一起使用的日志记录代码的预构建代码。

除此之外,它还会自动将代码添加到捕获异常并记录异常的方法中。

这完全取决于您是否乐意使用log4net日志记录框架或者更愿意自己动手​​。

答案 8 :(得分:0)

在vb.net中,可以向catch语句添加“When”限定符(例如,当Ex.Message.Contains(“Sorry”)'时,'Catch Ex as ObjectDisposedException')。这可以用于记录putposes(例如'Catch Ex as Exception当LoggingFunctionThatReturnsFalse(Ex)'不会捕获任何异常,但会将它们全部记录下来)并且看起来像是一个在C#中有用的功能。最后我听说,该功能仅在vb.net中可用(不确定如果在vb.net中使用这样的功能编译代码并反编译为C#会发生什么情况。)

答案 9 :(得分:0)

你可以在Global.asax Application_Error事件中添加一些内容。

我已经使用这种方法完成您在原始帖子中描述的内容,记录错误并通过电子邮件发送通知。