2012-01-11 37 views
10

什么?
我正在开发,需要保持一个控制台应用程序运行24/7 不管什么
有什么办法从一些未处理的异常在“一些线索某处”发生越来越炸毁停止多线程应用程序?
即使发生未处理的异常,也要保持应用程序正常运行

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

这是说,我知道如果由于和UnhandledException(我已经实现)而导致应用程序崩溃,则可能无法从“内部”重新启动应用程序。

到目前为止,我已经使用Quartz.net的FileScan作业和标志文件来检测这样的东西,并从外部重新启动应用程序。但这听起来对我来说很难受。我想找到更干净,更快捷,更肮脏的东西。

停止投票/狙击警告:我知道这可能不可能“按原样”。
请创造性/有益的而不是突然的批评,并认为这更多的是一个“开放式问题”

+2

所以...你为你的“开放式问题”添加一个“downvote”警告,然后downvote每个人试图帮助你。尼斯... – 2012-01-11 17:28:11

+0

@EthanCabiac对不起,你的回答“不是真的”是我首先评论的原因。在编辑之后,这是不同的。我会将其标记为答案,因为这是我自己贴出的答案给自己的选择。让我们来和平:) – 2012-01-11 22:45:58

回答

7

您需要附加一个事件处理UnhandledException事件对当前的AppDomain:

AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler

的处理函数中,你将不得不以某种方式保存足够的状态(到文件,数据库等)为重新启动的应用程序传递到新线程。然后通过致电System.Diagnostics.Process.Start("MyConsoleApp.exe")实例化控制台应用程序的新实例。

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

+1

这已经实施。这绝不会有助于任何重新启动。应用程序将在处理程序完成其工作后退出 – 2012-01-11 17:18:24

+1

@Mika:如果执行异常处理程序的方式不会重新启动程序,那不是异常处理程序的错误,这只是您未在UnhandledExceptionHandler中实现的行为。 – 2012-01-11 17:30:26

+0

@RobertP:这是一个非常重要的问题:异常处理程序会按照它告诉的是,但是,如果我错了,纠正我,应用程序IS在处理程序退出后立即终止。这使我的观点:它不允许应用程序保持活力。 – 2012-01-11 17:42:51

11

如果要全天候运行,无论如何,为什么不write it as a Windows service,并采取内置恢复选项的优势进入窗户?

Configuring Recovery Services

这种方法的优点是能够生存机器重新启动额外的优势,它会记录故障/重新启动系统事件日志。

+0

我真的想要避免使用服务并保持一切不受操作系统限制 – 2012-01-11 17:11:55

+1

您需要支持哪些操作系统?奇怪的是,你会在C#中进行非Windows编程。 – JohnFx 2012-01-11 17:13:52

+1

@Mika:然后从操作系统特定部分中分离非操作系统特定部分。您可以编写多个对象或库。 :) – 2012-01-11 17:16:59

5
  • 不能保持一个进程运行“不管是什么”。如果这个过程被杀了怎么办?
  • 不想保持一个进程运行“不管是什么”。如果进程状态被损坏,如果它继续运行会发生“坏事”?
+1

我说过“请不要给教训”:-)我已经习惯了SOF这样的非答案,但他们总是痒我。不要这么伤人!通过“不管物质是什么”我的意思是“不管物质在程序中发生了什么错误”! PLUS,如果进程状态已损坏,我将通过邮件通知并在服务器上看到它。另外我有我的糟糕的状态管理逻辑。但我需要它来保持东西在夜间运行并保持在一个顺畅的状态。 – 2012-01-11 17:15:44

+3

@mika:你向你显然不明白的东西寻求帮助。如果你不想要一个“课程”,那么不要求求帮助。 – 2012-01-11 17:30:05

+1

由于某些原因,整篇文章感觉就像是Raymond Chen博客帖子的开头。 – JohnFx 2012-01-11 17:35:13

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

如果您使用的.Net 2.0及以上,答案是你可以”吨。

在.NET Framework 1.0和1.1版,发生在比所述主应用程序线程是 由运行时捕获的其他线程,因此不导致应用程序终止 未处理的异常 。因此,UnhandledException事件有可能在没有应用程序终止的情况下引发 。从.NET Framework版本2.0开始,删除了子线程 线程中未处理异常的反向支持,因为此类无提示失败的累积影响包括性能下降,数据损坏和锁定,这些锁定都很难调试。有关更多信息,请参阅 ,其中包括运行时未终止的情况列表,请参阅 受管理线程中的例外情况。

从这里摘自:

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

如果你希望你的应用程序中生存的,那么什么事都逃不过你需要在你的方法非常积极的try/catch。

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

+0

谢谢你的明智指示。非常有教导性的确。 – 2012-01-11 22:40:27

相关问题