模拟环境中的异常.退出
本文关键字:异常 退出 环境 模拟 | 更新日期: 2023-09-27 17:50:47
生产控制台应用程序,每晚午夜前通过 Environment.Exit(0( 关闭,在 期间偶尔会遇到异常。Exit(( 使控制台应用程序挂起,并显示"应用程序已停止工作"屏幕。
这会导致进程无法正确清理,并且午夜后重新启动失败,因为先前的进程仍然徘徊。
由于我无法确定导致 Environment.Exit 中异常的原因,因此我希望至少在它发生时优雅地处理它,并确保该过程完全关闭。为此,我想模拟 .Exit(( 但我还没有找到会在 .退出((。
有谁知道如何模拟 Environment.Exit 期间的异常?
当然,复制很容易:
private static void Main()
{
try
{
new ItsATrap();
Environment.Exit(0);
}
catch (Exception ex)
{
Console.WriteLine("During exit: {0}", ex);
}
}
private class ItsATrap
{
~ItsATrap()
{
throw new InvalidOperationException("Ooops!");
}
}
请注意,在上面的示例中,During exit
文本永远不会打印。
您可以通过安装如下处理程序来捕获未经处理的异常:
AppDomain.CurrentDomain.UnhandledException += (sender, args)
=> Console.WriteLine("Unhandled: {0}", args.ExceptionObject);
这样,您就有机会记录它们。
所以......检查你的终结器,看看他们是否可以投掷。
此外,请确保它们不使用其他托管资源,因为最终确定顺序不是确定性的。像往常一样,Eric Lippert有一些关于这个主题的好文章可以阅读。
你这里有一个XY问题。您想要模拟异常,因为您不知道还可以执行哪些操作。与其模拟您不完全知道的东西,不如尝试找出问题的真正原因并修复它。
收集故障转储 (MSDN( 并将其加载到 Visual Studio 中。只要它位于 C# 代码中的某个位置,它就应该显示行号。
另请参阅:如何为 .NET 进行良好的故障转储?在 Stack Overflow 上。
按照其他答案中的建议修改代码可能会更改时间,并且可能会降低异常的可能性或发生在不同的位置。很高兴您可以重现问题并修复它,而不是稀释它。
使用已释放/最终的对象可能会导致它。发生这种情况是因为没有固定的定稿顺序,因此例如,尝试在已定稿的Stream
上编写内容的手工记录器将导致异常(手工制作,因为"专业"记录器知道这一点:-((。
您可以尝试在调用记录在此期间发生的每个异常的Environment.Exit
之前安装首次机会异常处理程序。像这样:
object lck = new object();
AppDomain.CurrentDomain.FirstChanceException += (sender, e) =>
{
lock (lck)
{
File.AppendAllText("log.txt", string.Format("{0}: {1}", DateTime.Now, e.Exception.ToString()));
}
};
Environment.Exit(0);