【问题标题】:Detecting and restarting my crashed .NET application检测并重新启动我崩溃的 .NET 应用程序
【发布时间】:2009-02-08 14:42:38
【问题描述】:

如何检测到我的 .NET 应用程序已崩溃,然后重新启动它?

【问题讨论】:

  • 我找到了这个问题的一些解决方案(在我问之前),所以我认为在 SO 中有答案会很好。如果您有其他答案,请成为我的客人。或者只是投票选出最佳答案来指导他人。另外,请在您认为合适的情况下重新标记此问题。
  • 添加了有关重新启动控制台应用程序的信息,因为这显然是您正在使用的。

标签: .net


【解决方案1】:

另一种解决方案(基于this example)是创建一个控制应用程序的启动器:

class LauncherProgram
{
    static int count = 3;

    static void Main()
    {
        Launch();
        Thread.Sleep(Timeout.Infinite);
    }

    static void Launch()
    {
        Process process = new Process();
        process.StartInfo.FileName = "MyApp.exe";
        process.EnableRaisingEvents = true;
        process.Exited += LaunchIfCrashed;
    }

    static void LaunchIfCrashed(object o, EventArgs e)
    {
        Process process = (Process) o;
        if (process.ExitCode != 0)
        {
            if (count-- > 0) // restart at max count times
                Launch();
            else
                Environment.Exit(process.ExitCode);
        }
        else
        {
            Environment.Exit(0);
        }
    }

【讨论】:

  • 唯一可能的升级是让“看门狗”成为 Windows 服务。
  • 最好添加一些时间戳代码并检测应用是否在启动时崩溃
  • 恐怕我帮不上那个忙,@AshK。对不起。
【解决方案2】:

如果这是一个 Windows 窗体应用程序:

  • 在 App.Config 中设置 jitDebugging = true。这可以防止触发内置的 Windows 窗体未处理的异常处理程序。

现在不管这是 Windows 窗体应用还是控制台应用:

  • 注册 Application.ThreadException 事件,例如在 C# 中:

    Application.ThreadException += new Threading.ThreadExceptionHandler(CatchFatalException);

此时,您的应用已经进入黑洞。接下来会发生什么取决于这是否是 Windows 窗体应用程序:

  • 如果是 Windows 窗体应用,请在 CatchFatalException 事件处理程序中调用 Application.Restart 方法。
  • 否则,您将需要 p/invoke 到 application restart and recovery 本机函数。该链接讨论了 Vista,但在我的测试中,它在 XP 上也能正常工作。

【讨论】:

  • 谢谢。控制台应用程序是否可以执行类似于Application.ThreadException += MyHandler; 的操作?
  • 是的,控制台应用也可以做到这一点。
  • 但是它无法访问Application类,是吗?
  • 如果您添加正确的命名空间,它确实可以访问 Application 类。但是在我的测试中,我看到了一个“不支持”的异常,所以你是对的,这对控制台应用程序不起作用。我将更改我的答案以反映这一点。
【解决方案3】:
  • 在 AppDomain 中运行工作;使用主 AppDomain 对其进行监控(但不能防止进程终止)
  • 大量异常处理!即不要让致命错误破坏进程
  • 在已经内置回收利用的东西中运行它 - 例如 IIS

【讨论】:

  • 谢谢马克。您能否添加一个示例,说明如何实施您建议的基于 AppDomain 的解决方案?
  • 假设这是一个 Windows 窗体或控制台应用程序,您可以使用 Application.Restart - 有关详细信息,请参阅我的答案。
【解决方案4】:

一个可能的解决方案是创建另一个进程来监视您的应用程序,如果它被终止,则重新启动它:

class ProcessMonitorProgram
{
    const string myProcess = "MyApp.exe";

    static void Main()
    {
        new Timer(CheckProcess, null, 0, 60 * 1000);
        Thread.Sleep(Timeout.Infinite);
    }

    static void CheckProcess(object obj)
    {
        if (Process.GetProcessesByName(myProcess).Length == 0)
            Process.Start(myProcess);
    }
}

这个解决方案的一个问题是它会一直重启进程,直到这个监控应用程序本身被终止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-09
    • 2016-02-23
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多