【问题标题】:How to delay 5 min before starting a windows service?如何在启动 Windows 服务之前延迟 5 分钟?
【发布时间】:2011-08-10 11:11:54
【问题描述】:

我正在使用 .Net 4 构建一个简单的 windows 服务,当我想在启动服务之前延迟 5 分钟时会出现问题。

protected override void OnStart(string[] args)
{
    // make a 5 min delay
    // do something
}

但几秒钟后服务停止并给我一个超时错误(在事件日志中看到)。 我该怎么办?

【问题讨论】:

    标签: c# windows-services


    【解决方案1】:

    在一个新线程中启动您长时间运行的进程,因此不要阻塞OnStart 方法。示例:

    using System.Threading;
    
    protected override void OnStart(string[] args)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback((_) =>
        {
            Thread.Sleep(5 * 1000 * 60);//simulate 5 minutes work
    
           // do something
        }));
    }
    

    【讨论】:

    • 是的。好主意。忽略操作系统中的 windows 延迟服务启动选项,然后围绕它们进行手动编码。
    • @TomTom: Yes. Good idea. Ignore windows delayed service start options from the operating system, then handcode around them. 为什么是 -1 呢?你是不是弄错了??
    • TomTom 你酸吗所有版本的windows都支持延迟服务选项,因为我用的是windows 2003。
    • 不,只有最新的。 2003 年是生命的尽头。
    • @TomTom: 2003 仍然在延长支持 4 年。我们并不总是可以选择我们使用什么,或者我们的客户使用什么。
    【解决方案2】:

    不要。服务必须在被要求时启动。 OnStart 必须返回。快

    也就是说,服务可以等待 5 分钟,直到它执行某事,但您不能只是停止启动周期。

    启动它,然后让工作线程等到它做某事。

    也就是说,有一个配置条目允许延迟启动服务。它配置FOR 服务,就像Manual, Automatic 有一个delayed 条目。这样可以确保服务仅在机器有一点时间从启动开始稳定下来时才启动。这可能会更好/足够好。

    【讨论】:

    • 你能解释一下配置条目吗?请。
    • 打开一个windows服务配置,看选项,用google。没那么难,加油。让我来做。谷歌“Windows 服务启动延迟”,第二个条目是...techrepublic.com/blog/datacenter/…
    • @TomTom 会是不错的解决方案,但只支持Win7、Vista和2008服务器...
    【解决方案3】:

    OnStart 方法需要及时返回,否则会出现超时错误。

    您需要做的是从OnStart 启动一个线程,并在该线程中等待 5 分钟,然后才能真正启动您的服务。所以你的OnStart 方法变成了:

    serviceThread = new Thread(new ThreadStart(workerClass.WorkerMethod));
    
    serviceThread.Start();
    

    WorkerClass.WorkerMethod 实际启动服务。

    【讨论】:

      【解决方案4】:

      当服务被告知启动或 Windows 认为它​​出现故障时,它必须做出响应。所以你有两个选择:

      1. 编写一个单独的应用程序,在启动时运行,等待 5 分钟,然后启动服务。

      2. 启动服务,并在它开始执行任何业务逻辑之前将其延迟五分钟。只要 Windows 认为它​​正常启动,它就很高兴。

      类似这样的:

      private static Timer t;
      protected override void OnStart(string[] args)
      {
          t = new Timer(5000*60);
          t.Elapsed += new ElapsedEventHandler(OnTimedEvent)
          t.Start()
      }
      
      private static void OnTimedEvent(object source, ElapsedEventArgs e)
      {
          // real code here
      }
      

      【讨论】:

        【解决方案5】:

        我不明白您为什么要将服务启动例程延迟 5 分钟。如果服务例程需要更长的时间,服务控制管理器可能会中止所有操作,因此您的服务无法启动。您宁愿需要在 OnStart 方法中启动一个线程/定时器,并在线程/定时器过程中等待 5 分钟。

        protected override void OnStart(string[] args)
                {              
                    Thread processor= new Thread(ThreadProc);
                    processor.Start();
                }
        
                private void ThreadProc()
                {
                    while (true)
                    {
                        Thread.Sleep(TimeSpan.FromMinutes(5));
        
                    }
                }
        

        【讨论】:

          【解决方案6】:

          使用 System.Timers.Timer 来推迟您的操作...这是我的一项服务中的一些代码。我使用 defer 的原因是,如果从 onstart 事件返回的时间过长,Windows 会假定服务已损坏。因为我在服务第一次启动时做了很多事情,所以我只需创建一个计时器就可以非常快速地启动服务,然后让该事件处理真正的启动内容。

              protected override void OnStart(string[] args)
              {
                  try
                  {
                      // Using a timer Event to start asynchronously
                      StartupTimer = new Timer();
                      StartupTimer.Elapsed += StartupTimer_Elapsed;
                      StartupTimer.AutoReset = false;
                      StartupTimer.Interval = 5*60*1000;
                      StartupTimer.Start();
                  }
                  catch (Exception ex)
                  {
                      LogMessage(true, ex.ToString());
                  }
              }
          
              private void StartupTimer_Elapsed(object sender, ElapsedEventArgs e)
              {
                  try
                  {
                      RunSetup(true);
                  }
                  catch (Exception ex)
                  {
                      LogMessage(true, ex.ToString());
                  }
              }
          

          【讨论】:

            【解决方案7】:

            直接的方法是使用 System.Threading.Timer 并将到期时间设置为 5 分钟,请参阅System.Threading.Timer 了解更多信息。

            【讨论】:

              【解决方案8】:

              问题的根源在于,如果服务启动时间较长,Windows 会认为它出现故障并杀死它。

              您可以通过首先告诉 Windows 该服务需要一些时间才能启动来解决此问题。

              要做到这一点,请参阅这个 SO 问题的答案:windows service startup timeout

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-08-17
                • 2013-11-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-06-20
                相关资源
                最近更新 更多