【问题标题】:Prevent console application from terminating防止控制台应用程序终止
【发布时间】:2012-08-15 07:38:18
【问题描述】:

我有一个 C# 4.0 Windows 控制台应用程序,它应该运行 24*7*365。 (我有一个 Windows 服务来监视这个应用程序,并在它由于某种原因终止时启动它)。这个控制台应用程序的启动涉及一些复杂的资源消耗活动——所以我必须确保控制台应用程序不会频繁重启。控制台应用程序有 3 个 System.Timers.Timer 实例,它们在计时器经过时执行一些活动(间隔分别为 10 秒、15 秒和 2 小时)。防止控制台应用程序终止并使其保持活动状态的正确方法是什么?有人可以推荐一下吗!

【问题讨论】:

  • 你现在如何让它活着?你肯定有某种循环吗? while(true) Console.ReadKey() 够吗?
  • 您首先需要说明导致它终止的原因
  • 我不得不问:您真的有一个服务要监视并启动永远运行的控制台。 ..?你为什么不把代码移到服务中(因为你描述的是服务的行为)
  • @MarcGravell 它可能正在使用来自用户会话的资源,或者它可能会在运行时报告信息。但我同意,为什么不把逻辑放在服务中。
  • @Joseph 将逻辑放入可从服务或控制台应用程序使用的类库中,为您提供更大的灵活性。

标签: c# .net console-application


【解决方案1】:

根据您在 cmets 中所说的,您拥有控制台应用程序的唯一原因是您可以阅读调试消息。这个答案会偏离这个假设。

控制台应用程序不够可靠,无法执行您想做的事情,您会遇到很多情况,该应用程序无法启动或可能多次启动(如果没有人登录,您会怎么做?什么如果多人登录,你会这样做吗?)

最好的办法是将这种密集操作编写为服务,然后将输出到控制台的任何诊断信息放入事件日志或放入调试器。

如果您想将消息写入应用程序事件日志,您只需将信息写入this.EventLog.WriteEntry(message)。这将在应用程序事件日志中为您的服务生成一个信息事件。如果您想将严重性提高到警告或错误,您只需要使用the other overload

如果您想写入与应用程序不同的日志(如您自己的日志),您需要让服务的installer 创建您需要的任何源/日志(如果您需要帮助,请提出一个新问题)。然后将您的服务中的AutoLog 设置为false,然后创建您自己的指向新日志的事件日志实例。

如果您希望仅在诊断问题时显示日志,最简单的解决方案是将您的 Console.WriteLine(message) 语句更改为 Debugger.Log(1, "DebugLogging", message + Environment.NewLine)。当您在服务运行时附加到服务时,这将导致您的消息显示在“调试”输出窗口中(您知道如何附加到服务以在其上运行调试器吗?如果不问一个新问题它)。我不建议使用Debug.WriteLine(message),除非您从不打算在发布模式下进行诊断。这是因为Debug.WriteLine 具有属性[Conditional("DEBUG")]。这样做的目的是仅在编译时设置了 DEBUG 标志时才执行该函数,并且 Release 没有设置该标志。


这是简单的解决方案,如果您想要更强大的解决方案,我建议您学习如何使用log4net。 Log4net 将让您完成以上所有工作,以及更多。例如,您可以通过配置文件控制写入事件日志的数量(程序甚至不需要重新启动即可使用新设置开始记录,它会检测您何时执行保存。)

通过这种方式,您可以在代码中添加详细的日志记录消息,但仅在需要时通过更改 XML 配置文件中的一项设置来打开它们。

如果您对设置两个热门建议中的任何一个或设置 log4net 有任何疑问,请随时就这些主题提出新问题。

【讨论】:

  • 谢谢,我已经在使用 Log4Net。现在我已将整个功能实现为服务。
【解决方案2】:

您可以简单地使用 Console.ReadLine() 来保持控制台处于活动状态。但是 Windows 服务可能是您想要的。

【讨论】:

    【解决方案3】:

    while (Console.ReadLine() != "I really want to stop this application") { } 或类似的东西?

    考虑类似的应用程序(例如 Minecraft...),您会遇到如下循环:

    string command;
    Console.Write("> ");
    while ((command = Console.ReadLine()).ToUpper() != "STOP")
    {
        // Do something else based on the command
        ...
    
        Console.Write("> ");
    }
    

    【讨论】:

    • 由于控制台应用程序是从 Windows 服务触发的,我不会看到控制台应用程序停止它 - 这意味着基本上没有桌面交互。
    • 在这种情况下,我必须选择“从服务运行代码”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 2019-08-29
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多