gpt4 book ai didi

c# - 吞下未处理的异常(调试器除外)

转载 作者:行者123 更新时间:2023-11-30 13:01:10 24 4
gpt4 key购买 nike

我正在使用 .NET 4.0 框架维护旧版 C# Winform 应用程序。该应用程序运行良好,但偶尔由于应用程序中的错误,当应用程序在数据库中创建无效数据时,应用程序将无法正常运行。

在某些时候,我们将(无效/损坏的)数据绑定(bind)到数据网格,这会在它尝试将空列映射到数据网格列时导致大量错误。

An exception of type 'System.InvalidCastException' occurred in mscorlib.dll but was not handled in user code

Additional information: Object cannot be cast from DBNull to other types.

还有

An exception of type 'System.Reflection.TargetInvocationException' occurred in System.Windows.Forms.dll but was not handled in user code

当在 Visual Studio 调试器下运行时,错误会导致显示一个漂亮的弹出窗口,详细说明错误并允许我查看发生错误的行。

在这种特殊情况下,我知道问题出在哪里,所以我可以很容易地纠正它。但是,此类错误在应用程序的其他部分中发生得太频繁了,因此并不总是很明显发生了什么,而且我的用户并不总是提供良好的错误报告。为了尝试解决这个问题,我想向应用程序添加日志记录(使用 log4net),这在我们的情况下有效,因为每个用户都有自己的应用程序副本,因此我可以在事后获取每个用户的日志。

使用来自 stackoverflow 以及其他各种来源的提示,我发现了很多关于为这些未处理的异常设置处理程序的有用信息。不幸的是,大多数“未处理”异常都没有调用我的处理程序。

应用程序最相关的部分如下:

static class Program {
private static readonly ILog log = LogManager.GetLogger("Main");

static void Main() {
// Add some error handlers which log error data to the logfile
//
// For UI events (set the unhandled exception mode to force all Windows Forms
// errors to go through our handler)
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += new ThreadExceptionEventHandler(delegate(object s, ThreadExceptionEventArgs e) {
ExceptionLogger(e.Exception);
});
// Non-UI thread exceptions
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(delegate(object sender, UnhandledExceptionEventArgs e) {
ExceptionLogger(e.ExceptionObject as Exception);
});

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
log.Debug("Starting Application");
Application.Run(mainForm = new MainForm());
}

private static void ExceptionLogger(Exception e) {
log.Error("Unhandled Error", e);
string errorMsg = "An application error occurred. Please contact the administrator with the following information:\n\n";
errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace;
if (MessageBox.Show(errorMsg, "TLMS Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop) == DialogResult.Abort)
Application.Exit();
}

如果错误直接发生在我自己的代码中,异常处理程序似乎可以工作,但如果/当错误直接发生在 .NET 库中时,则不会调用该处理程序,我希望为 所有未处理的异常,包括我编写的代码之外的异常

如果我可以在事后在调试器中重新创建准确的用户步骤,那么能够使用调试器来追踪错误是非常宝贵的。但是,在任何时候都不会调用 ExceptionLogger,无论是独立运行还是在调试器内部运行,并且没有任何视觉指示表明发生了任何错误。由于异常被抑制,用户有时直到为时已晚才意识到他们所做的一切都完全搞砸了,数据甚至更加损坏。

应用程序平台正在 x86 上构建和运行(显然,如果在 x64 上运行,异常可能会丢失),应用程序已经在 64 位和 32 位平台上进行了测试,行为没有变化。

最佳答案

因此,当应用程序在调试器中运行时,您只会看到“但未被处理”。当它在调试器之外运行时,异常会被抑制。如果我做对了,那么我仍然认为该应用程序会处理异常,因为调试器有时会更改应用程序的行为。

我确认 InvalidCastException 是一组异常中的一个,如果异常上下文是非托管代码,.NET 4+ 会以不同方式处理这些异常。应用程序可以覆盖此特殊处理(请参阅 All about Corrupted State Exceptions in .NET 4 ),但调试器可能会忽略覆盖。有很多关于此的网络资源,另请参阅 MSDN Magazine 中的一个。 .

编辑:如果您的应用用户安装了 .NET 3.5 或更低版本,则该应用无需应用上述资源中描述的覆盖。

关于c# - 吞下未处理的异常(调试器除外),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20359923/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com