即使发生未处理的异常,也要保持应用程序运行

时间:2012-01-11 17:02:32

标签: c# .net

什么?
我正在开发一个需要保持全天候运行的控制台应用程序无关紧要有没有办法阻止多线程应用程序因为某些未处理的异常而被炸毁某个地方的某个帖子“?

为什么?
请不要提供诸如“你应该管理所有例外”,“这应该永远不会发生”等课程。我有我的理由:我们正在进行测试部署,我们需要保持运行,记录异常,然后重新启动所有线程。如果发生了任何未计划的并导致抛出未处理的异常,则需要检测它并调用一些方法来重新启动所有线程(由于层设计原因,原子性是不可能的)

这就是说,我知道如果因为和UnhandledException(我已经实现了)而导致应用程序从“内部”重新启动是不可能的。

到目前为止,我已经使用了Quartz.net的FileScan Job和一个Flag文件来检测这样的东西并从外部重启应用程序。但这对我来说听起来很糟糕。我想找一些更干净,更快捷,更脏的东西。

DownVoting / Sniping警告:我知道这可能不是“原样”。
请有创意/乐于助人,而不是突然批评,并将其视为“公开问题”

5 个答案:

答案 0 :(得分:11)

如果要以24/7全天候运行,为什么不只是write it as a Windows service并利用Windows内置的恢复选项?

Configuring Recovery Services

此方法还具有能够在计算机重新启动后继续运行的额外优势,并且会在系统事件日志中记录失败/重新启动。

答案 1 :(得分:7)

您需要将事件处理程序附加到当前AppDomain上的UnhandledException事件:

AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler

在处理程序内部,您必须以某种方式保存足够的状态(到文件,数据库等),以便重新启动的应用程序传递给新线程。然后通过调用System.Diagnostics.Process.Start("MyConsoleApp.exe")来实例化控制台应用程序的新实例。

要非常小心地引入逻辑以避免连续的崩溃/重启/崩溃/重启循环。

答案 2 :(得分:4)

  • 无法让流程“无论如何”运行。如果这个过程被杀了怎么办?
  • 不希望让流程“无论如何”运行。如果进程状态被破坏,如果它继续运行会发生“坏事”,该怎么办?

答案 3 :(得分:2)

我可以想到以下解决方案中的一些缺点,但目前对我来说已经足够好了:

static void Main()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
        CS = new ConsoleServer();
        CS.Run();            
    }

    public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Exception exception = (Exception)e.ExceptionObject;
        Logger.Log("UNHANDLED EXCEPTION : " + e.ExceptionObject.ToString());
        Process.Start(@"C:\xxxx\bin\x86\Release\MySelf.exe");
    }

答案 4 :(得分:2)

如果您使用.Net 2.0及以上版本,答案是您不能。

  

在.NET Framework 1.0和1.1版中,出现未处理的异常   发生在主应用程序线程以外的线程中   由运行时捕获,因此不会导致应用程序   终止。因此,UnhandledException事件可能是   在没有申请终止的情况下提出。从.NET开始   框架版本2.0,这个支持未处理的子例外   线程被删除了,因为这种沉默的累积效应   失败包括性能下降,数据损坏和   锁定,所有这些都很难调试。欲获得更多信息,   包括运行时未终止的案例列表,请参阅   托管主题中的例外情况。

从这里采取:

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

如果你希望你的应用程序存活下来,那么你将需要非常积极的尝试/捕获你的方法,所以没有逃脱。

我建议使用其他人提到的Windows服务。它与控制台应用程序相同,但顶部有一些额外的服务层代码。您可以使用控制台应用程序并轻松将其转换为服务应用程序。只需要覆盖service.start / pause / stop方法。