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

C# 即使发生未处理的异常,也要保持应用程序运行,c#,.net,C#,.net,什么? 我正在开发一个控制台应用程序,无论发生什么情况,它都需要24/7运行有什么方法可以阻止多线程应用程序被“某个线程某处”中发生的未经处理的异常所破坏? 为什么? 请不要讲授“您应该管理所有异常”、“这永远不会发生”等课程。我有我的理由:我们正在测试部署中,我们需要保持此运行,记录异常,并重新启动所有线程。如果发生任何未计划的异常,并导致引发未处理的异常,则需要检测该异常并调用某些方法来重新启动所有线程(由于层设计,原子性是不可能的) 话虽如此,我知道如果应用程序因为未经处理的异常(我已经实

什么?
我正在开发一个控制台应用程序,无论发生什么情况,它都需要24/7运行
有什么方法可以阻止多线程应用程序被“某个线程某处”中发生的未经处理的异常所破坏?

为什么?
请不要讲授“您应该管理所有异常”、“这永远不会发生”等课程。我有我的理由:我们正在测试部署中,我们需要保持此运行,记录异常,并重新启动所有线程。如果发生任何未计划的异常,并导致引发未处理的异常,则需要检测该异常并调用某些方法来重新启动所有线程(由于层设计,原子性是不可能的)

话虽如此,我知道如果应用程序因为未经处理的异常(我已经实现)而崩溃,那么可能无法从“内部”重新启动应用程序

到目前为止,我使用了Quartz.net的FileScan作业和一个标志文件来检测类似的内容,并从外部重新启动应用程序。但我觉得这听起来很讨厌。我想找一种更干净、不那么快、不那么脏的东西


向下投票/狙击警告:我知道“按现状”可能不可能做到这一点
请发挥创意/提供帮助,而不是突然提出批评,并将此更多地视为一个“开放性问题”

如果它要全天候运行,为什么不干脆利用windows内置的恢复选项呢

这种方法的另一个优点是能够在机器重新启动后生存下来,并将故障/重新启动记录在系统事件日志中。

  • 无论发生什么情况,您都不能保持进程运行。如果进程被终止怎么办
  • 不想让流程“无论如何”都保持运行。如果进程状态被破坏,如果它继续运行,就会发生“坏事情”,该怎么办

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

AppDomain.CurrentDomain.UnhandledException+=UnhandledExceptionHandler

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


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

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

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");
    }

如果您使用.NET2.0及更高版本,答案是您不能

在.NET Framework版本1.0和1.1中,未经处理的异常 在主应用程序线程以外的线程中发生的 被运行时捕获,因此不会导致应用程序 终止因此,未处理的异常事件有可能 在应用程序未终止的情况下引发。从.NET开始 框架版本2.0,该版本支持子系统中未处理的异常 线程被删除了,因为这种静默的累积效应 故障包括性能下降、数据损坏和 锁定,所有这些都很难调试。欲了解更多信息, 包括运行时未终止的情况列表,请参阅 托管线程中的异常

摘自这里:

如果您想让应用程序存活下来,那么您需要非常积极地尝试/捕获您的方法,这样就不会有任何东西逃脱


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

我真的希望避免使用服务,并保持所有非操作系统的界限您需要支持什么操作系统?看起来很奇怪,你会用C#做非windows编程。@Mika:然后将非操作系统特定部分与操作系统特定部分分开。允许您写入多个对象或库。:)@米卡:也许你不明白服务的意义。它是您编写的代码,用于执行需要随时执行的特定工作。当然,你可以自己做;C#是图灵完备的,所以您需要的任何东西都是可能的。使用服务时,您恰好将“出现故障时重新启动”部分留给操作系统。Microsoft编写了代码来为您完成这项工作。可以用它。事实上,如果你使用操作系统来做这件事会更好,因为微软几十年来一直雇佣高技能人员来解决这个问题。他们帮你解决了。利用它。:)@MikaJacobi:对Windows服务的支持是Windows的一部分。你可以控制旋钮的设置方式,但如果它对所有现有的Windows服务都足够好,那么很可能对你来说就足够好了。我说了“请不要上课”:-)我已经习惯了在软件上这样的非答案,但它们总是让我感到痒。别那么刻板!我所说的“不管什么”是指“不管程序中发生了什么错误”!另外,如果进程状态已损坏,我将收到邮件通知,并在服务器上看到它。另外,我的状态管理逻辑也很糟糕。但是我需要它来保持东西运转,如果有什么问题,我会在晚上重新点菜。@mika:你向我寻求帮助,但你显然不明白。如果你不想得到“教训”,那就不要寻求帮助。出于某种原因,这篇文章感觉就像是陈雷蒙博客文章的开始。@EthanCabiac:你显然把“开箱思考”误认为是“缺乏理解”。此外,我还说:“我知道这可能是不可能的。”我只是很好奇,我从不接受一个简单的“不”作为答案。有阿尔瓦