C# 是否存在任何在出现异常时触发的事件?
.Net framework中是否存在因异常而触发的事件。每当捕获到异常时,我都需要记录它。因此,如果存在一个事件,我可以订阅该事件并将异常记录在事件处理程序中。除了C# 是否存在任何在出现异常时触发的事件?,c#,.net,C#,.net,.Net framework中是否存在因异常而触发的事件。每当捕获到异常时,我都需要记录它。因此,如果存在一个事件,我可以订阅该事件并将异常记录在事件处理程序中。除了异常?我只需要在我的catch块中添加对日志模块的调用 比如: catch(YourException ex) { LogMyException(ex, [otherParamsYouNeed]); //Other Exception Handling } 如果你想记录某件事情的状态,不管成功与否,请使用finally{}
异常
?我只需要在我的catch
块中添加对日志模块的调用
比如:
catch(YourException ex)
{
LogMyException(ex, [otherParamsYouNeed]);
//Other Exception Handling
}
如果你想记录某件事情的状态,不管成功与否,请使用finally{}
查看此未处理的异常。您正在查找的是venthandler,这是windows的,但我认为web也有类似的想法致以最诚挚的问候,
Iordan在WinForms中有
应用程序.ThreadException
事件,更一般的是AppDomain.CurrentDomain.UnhandledException
事件
但是请注意,在记录这些异常之后,建议关闭应用程序。它可能不再处于稳定状态。AppDomain类有一个事件,但我认为您不能订阅正在抛出的任何异常。是-对象上有一个事件: 仅供参考:您应该仅将这些处理程序用作最后手段-最好在
try
catch
块中捕获异常,尽管这可能并不总是可能的(例如,在第三方代码启动新线程的情况下)
此外,只有当异常未处理时才会触发此事件-据我所知,如果不将调试器附加到进程,就无法以这种方式通知捕获的事件。在ASP.NET中,可以通过处理页面错误事件在页面级别或在应用程序级别捕获未处理的异常(在global.asax或IHttpModule实现中)处理应用程序错误事件。这些事件不会给出实际的异常,因此您需要调用服务器以获取异常:
Exception ex = HttpContext.Current.Server.GetLastError();
您应该看看如何使用PostSharp进行一些面向方面的编程,您可以编写一个简单的日志属性并将其应用于整个程序集 您所需要的就是这样的东西:
[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.
...
}
抱歉,这有点冗长。要扩展BurningMonk给出的答案,您也可以尝试使用。这是用于插入日志框架的日志代码的预构建代码 除此之外,这将自动向您的方法添加捕获异常并记录它们的代码
这完全取决于您是否愿意使用log4net日志框架,还是更愿意自己使用它。在vb.net中,可以在catch语句中添加一个“When”限定符(例如“catch Ex as ObjectDisposedException When Ex.Message.Contains(“Sorry”)。这可以用于记录PutPOSE(例如,“Catch Ex as Exception When Logging Function that Returns False(Ex)”不会捕获任何异常,但会记录所有异常),这似乎是一个在C#中很有用的功能。不过,我最后听说,该功能仅在vb.net中可用(不确定如果在vb.net中使用此功能编译代码并反编译为C#会发生什么情况).您可以在Global.asax应用程序错误事件中放入一些内容
我使用此方法完全按照您在原始帖子中描述的方式进行操作,记录错误并通过电子邮件发送通知。但是,如果您想在方法中记录状态,这对您没有帮助。请确保在记录后包含
throw;
。+1,这些处理程序是记录未处理异常的最佳位置,这些异常将导致应用程序的终止。我认为这比接近故障点的“log and rethrow”要干净得多,因为.NET异常类已经保留了StackTrace之类的上下文信息。web等价物是HttpApplication。错误+1表示“您应该只使用这些处理程序作为最后手段”,我使用它来记录异常,通知用户并仅重新启动应用程序。否则,您可能会遇到各种问题。文档中不清楚,但订阅此事件似乎不会给您任何阻止AppDomain关闭的机会。这是正确的:这是C#不支持的CLR功能之一xpose。你可以通过捕获所有ObjectDisposedException
,检查它们的消息,并使用throw;
重新播放来做一些非常类似的事情。不确定它在性能上比较如何,但再一次,这是一个例外,所以谁在乎呢?@Steven Sudit:调试时,一个未捕获的例外Option将在抛出的位置中断执行;捕获和重试异常将在重试的位置中断执行。我不能否认在调试器下运行时存在差异,但我不会编写代码以使出现未捕获的异常。在最坏的情况下,顶级catch块
catch (Exception ex)
{
// log error
log.Error(ex);
// handle exception, rethrow, etc.
...
}