【问题标题】:How to re-start a console application if it crashes?如果控制台应用程序崩溃,如何重新启动它?
【发布时间】:2017-01-29 17:49:34
【问题描述】:

我在 C# 中创建了一个控制台应用程序。如何对这个应用程序进行编程,使其在崩溃后重新启动?

【问题讨论】:

  • 你运行它。如果它意外消失,它就会崩溃。:-)。但说真的,你是什么意思?
  • 您可以使用 System.Diagnostics 从另一个应用程序启动,也可以使用 Windows 任务计划程序启动它。我们需要更多信息才能更有帮助
  • 让您的控制台应用返回一个非零的“成功”退出代码。然后编写一个启动器应用程序来启动它,并等待它退出。如果退出代码不是特殊的“成功”代码,请再次启动控制台应用程序。

标签: c# .net console-application


【解决方案1】:

如果我正确理解您的问题,您想在发生崩溃时尝试重新启动控制台应用程序。在 C# 控制台应用程序中,定义为入口点的方法(通常是 static void main)是应用程序中调用堆栈的根。您基本上需要递归调用该方法。如果应用处于某种意外或不可恢复的状态,您需要确保应用最终会失败。

例如在主类中:

static int retryCount;
const int numberOfRetries = 3;
static void Main(string[] args)
{
    try
    {
        var theApp = new MyApplicationType(args);
        theApp.StartMyAppLogic();
    }
    catch (ExpectedExceptionType expectThisTypeOfException)
    {
        thisMethodHandlesExceptions(expectThisTypeOfException);
    }
    catch (AnotherExpectedExceptionType alsoExpectThisTypeOfException)
    {
        thisMethodHandlesExceptions(alsoExpectThisTypeOfException);
    }
    catch (Exception unexpectedException)
    {
        if(retryCount < numberOfRetries)
        {
            retryCount++;         
            Main(args);
        }
        else
        {
            throw;
        }
    }
}

【讨论】:

  • 没问题。没那么不好;)
【解决方案2】:
  1. 您可以使用看门狗来处理您的监视器并在崩溃时重新启动它: 见:What's the best way to watchdog a desktop application?

  2. 您可以改用 Windows 服务并设置它的恢复选项,如下所示:https://serverfault.com/questions/48600/how-can-i-automatically-restart-a-windows-service-if-it-crashes

  3. 您可以使用任务管理器中的计划任务来定期启动您的应用程序,并将其设置为仅在上一次运行结束时启动: https://support.microsoft.com/en-us/kb/323527

【讨论】:

    【解决方案3】:

    你可以试试这样的:

    static void Main(string[] args)
    {
        try
        {
            // Application code goes here
        }
        catch (Exception)
        {
            var applicationPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            Process.Start(applicationPath);
            Environment.Exit(Environment.ExitCode);
        }
    }
    

    基本上,将所有代码包装在一个try/catch 中,如果发生任何异常,程序将使用System.Reflection.Assembly.GetExecutingAssembly().Location; 检索.exe 位置,然后调用Process.Start 再次运行应用程序。

    【讨论】:

    • 我更愿意处理 AppDomain.CurrentDomain.UnhandledException 事件而不是这个解决方案。因此,您可以在可以恢复的情况下使用 try/catch..
    • 这在某些异常(如堆栈溢出或内存不足异常)的情况下将不起作用
    • 出现异常时物理退出和重启有什么意义?
    【解决方案4】:

    您应该从另一个应用程序(看门狗、调度程序、procmon、servman...)控制您的控制台应用程序。

    例如您可以将控制台应用程序创建为服务并通过服务管理器对其进行控制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      • 2017-08-02
      相关资源
      最近更新 更多