在Environment.Exit

时间:2015-05-26 20:16:41

标签: c# exception

每天午夜前通过Environment.Exit(0)关闭的生产控制台应用程序,偶尔在.Exit()期间遇到异常,导致控制台应用程序挂起,“应用程序已停止工作”屏幕。 / p>

这导致流程无法正常清理,午夜后重新启动失败,因为先前的流程仍然存在。

由于我无法确定导致Environment.Exit中的异常的原因,因此我希望至少在它发生时正常处理它并确保进程完全关闭。为此,我想在.Exit()之后模拟崩溃,但是我无法找到在.Exit()期间会产生异常的场景。

有没有人知道如何模拟Environment.Exit期间的异常?

3 个答案:

答案 0 :(得分:3)

当然,它很容易复制:

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有一些good articles来阅读这个主题。

答案 1 :(得分:1)

这里有XY问题。您想模拟异常,因为您不知道还能做什么。您应该尝试找出问题的真正原因并进行修复,而不是模拟您不确切知道的内容。

Collect a crash dump (MSDN)并将其加载到Visual Studio中。只要它在您的C#代码中的某个位置,就应该显示行号。

另请参阅:Stack Overflow上的How do I take a good crash dump for .NET?

根据其他答案中的建议修改您的代码可能会改变时间,并且可能会使异常更不可能或发生在不同的位置。很高兴您可以重现问题并修复它而不是稀释它。

答案 2 :(得分:0)

使用已处置/已完成的物体可能会导致它。发生这种情况是因为没有固定的最终确定顺序,因此例如手写的记录器试图在已经完成的Stream上写一些东西会导致异常(手工制作,因为"专业&#34记录员知道这个:-))。

您可以尝试在调用记录此期间发生的每个异常的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);