Ian*_*Ian 7 c# exception winforms
我有一个WinForm应用程序编写的C#地方,我把一个try-catch块放在Program.cs程序入口中的static void Main方法,就像这样在应用程序的开头:
using System;
using System.IO;
using System.Windows.Forms;
namespace T5ShortestTime {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
try {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new T5ShortestTimeForm());
} catch (Exception e) {
string errordir = Path.Combine(Application.StartupPath, "errorlog");
string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt");
if (!Directory.Exists(errordir))
Directory.CreateDirectory(errordir);
File.WriteAllText(errorlog, e.ToString());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它Application被放在一个try-catch块中,在catch块中,它唯一能做的就是创建一个错误日志文件.
现在,到目前为止一切顺利.我的应用程序运行良好,如果遇到崩溃,最后Exception应该被try-catch块捕获并存储在错误日志文件中.
但是,当我运行我的程序一段时间后,我得到一个未处理的异常(null引用).让我感到惊讶的是,异常不会创建错误日志文件.
现在,这篇文章显示它可能是由(ThreadException或HandleProcessCorruptedStateExceptions两个最受欢迎的答案)引起的,但我的案例显示了一个简单的null引用异常:
Problem signature:
Problem Event Name: CLR20r3
Problem Signature 01: T5ShortestTime.exe
Problem Signature 02: 2.8.3.1
Problem Signature 03: 5743e646
Problem Signature 04: T5ShortestTime
Problem Signature 05: 2.8.3.1
Problem Signature 06: 5743e646
Problem Signature 07: 182
Problem Signature 08: 1b
Problem Signature 09: System.NullReferenceException
OS Version: 6.3.9600.2.0.0.272.7
Locale ID: 1033
Additional Information 1: bb91
Additional Information 2: bb91a371df830534902ec94577ebb4a3
Additional Information 3: aba1
Additional Information 4: aba1ed7202d796d19b974eec93d89ec2
Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=280262
If the online privacy statement is not available, please read our privacy statement offline:
C:\Windows\system32\en-US\erofflps.txt
Run Code Online (Sandbox Code Playgroud)
那为什么会这样?
try-catch块应捕获最后一个Exception
这不会发生.除了一种情况,当您运行附带调试器的程序时.所以你肯定会相信它会起作用,每个人总是开始用F5运行他们的程序一段时间.
Application.Run()在其代码中有一个反向停止引发事件,try/catch-em-all在事件处理程序抛出未处理的异常时引发Application.ThreadException事件.这回站是真的,真的有必要,特别是在Windows x64版本7 非常不好的事情发生时,有没有异常处理程序.但是,当您使用调试器运行时,该后退不会到位,这使得未处理的异常难以调试.
因此,当您调试时,您的catch子句将运行.使未处理的异常太难以调试.当您在没有调试器的情况下运行时,您的catch子句将无法运行,您的程序将崩溃,就像您所描述的那样.使未处理的异常太难调试.
所以不要这样做.Application.Run()如何处理未处理的异常是使用Application.SetUnhandledExceptionMode()方法配置的.你会更喜欢这个版本:
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (!System.Diagnostics.Debugger.IsAttached) {
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
AppDomain.CurrentDomain.UnhandledException += LogException;
}
Application.Run(new Form1());
}
private static void LogException(object sender, UnhandledExceptionEventArgs e) {
string errordir = Path.Combine(Application.StartupPath, "errorlog");
string errorlog = Path.Combine(errordir, DateTime.Now.ToString("yyyyMMdd_HHmmss_fff") + ".txt");
if (!Directory.Exists(errordir))
Directory.CreateDirectory(errordir);
File.WriteAllText(errorlog, e.ToString());
AppDomain.CurrentDomain.UnhandledException -= LogException;
MessageBox.Show("Error details recorded in " + errorlog, "Unexpected error");
Environment.Exit(1);
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,您可以毫无问题地调试未处理的异常.Debugger.IsAttached测试确保调试器在事件处理程序崩溃时始终停止.如果没有调试器,它会禁用Application.ThreadException事件(它非常无用)并且倾向于监听所有异常.包括在工作线程中引发的那些.
您应该向用户发出警报,以便窗口不会消失而没有任何痕迹.我打算推荐MessageBox但是注意到这个bug目前在Windows 10上又回来了.叹了口气.
| 归档时间: |
|
| 查看次数: |
673 次 |
| 最近记录: |