【问题标题】:Windows Service always "Starting" because of infinite loop in OnStart() method由于 OnStart() 方法中的无限循环,Windows 服务总是“启动”
【发布时间】:2011-06-04 04:35:12
【问题描述】:

我编写了一个 Windows 服务,它定期执行一个 SSIS 包,将文档从 Server A 移动到 Server B

问题在于,为了做到这一点,我需要使用无限循环,它在服务启动时启动。

当然,我将这个循环放入OnStart() 方法中。不幸的是,服务从来没有发出它已经启动的信号,因为它永远不会到达这个方法的结尾......

以下是相关代码:

protected override void OnStart(string[] args)
{
    Application app = new Application();
    Package pkg = app.LoadFromDtsServer(@"MSDB\PullDoc", "Server", null);
    while (true)
    {
        DTSExecResult pkgResults = pkg.Execute();//Execute the package.
        EventLog.WriteEntry(pkgResults.ToString());
        Thread.Sleep(1000 * 60 * 5);//Sleep at least five minutes.
    }
}

我想这是一个常见问题,因为大多数服务应该无限期地运行。

关于如何让这个服务返回它已经启动的任何想法?

谢谢!

【问题讨论】:

    标签: windows-services


    【解决方案1】:

    您应该使用System.Threading.Timer 而不是无限循环。

    【讨论】:

    • 相关问题:当​​我使用定时器时,它会每5分钟调用一次我的回调方法,即使该方法还没有完成执行。有没有一种简单的方法让它在方法结束之前不计数?
    • @user:设置定时器只运行一次,然后在方法结束时再次启动。
    【解决方案2】:

    您的服务应该在不同的线程上工作。 OnStartOnStop 等方法用于处理来自 Windows 服务控制管理器 (SCM) 的服务命令,SCM 期望它们迅速返回。

    使用@SLaks 建议的System.Threading.Timer 可以实现这一点:计时器事件将在.NET 线程池中的线程上执行。您的 OnStart 方法只是启用计时器,而 OnStop 方法将其禁用(如果您愿意,OnPause 和 OnResume 也可以这样做)。

    【讨论】:

      【解决方案3】:

      你没有正确地这样做,你不应该阻止一个函数返回,你应该使用一个新的线程。正如建议的那样,您应该使用Timer 对象。 这是一个代码 sn-p 向您展示如何:

          private void OnElapsedTime(object source, ElapsedEventArgs e)
          {
               CopyAToB();
          }
          Timer timer = new Timer();
          protected override void OnStart(string[] args)
          {
              timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
              timer.Interval = 60000 * 5;
              timer.Enabled = true;
          }
          private void CopyAToB()
          {
              // do somethings
          }
      

      【讨论】:

      【解决方案4】:

      我建议您使用建议的 System.Threading.Timer,但这里是我将如何实现该功能的示例。

      在这个例子中,我让函数每小时触发 4 次,它会快速验证它是否仍在上一次调用中运行,如果是,则跳过它,否则它将创建一个新线程并触发该函数。

      Imports System.Threading
      
      Public Class myService
      
        Private myThreadingTimer As System.Threading.Timer
        Private keepRunning As Boolean = False
        Private processing As Boolean = False
      
        Protected Overrides Sub OnStart(ByVal args() As String)
          Dim myTimerCallback As New TimerCallback(AddressOf OnTimedEvent)
      
          If YourCheckHere() Then
            keepRunning = True
            myThreadingTimer = New System.Threading.Timer(myTimerCallback, Nothing, 1000, 1000)
          Else
            'What you want to do here
          End If
        End Sub
      
        Protected Overrides Sub OnStop()
          keepRunning = False
        End Sub
      
        Private Sub OnTimedEvent(ByVal state As Object)
          If Date.Now.Minute = 14 And Date.Now.Second = 31 Or Date.Now.Minute = 29 And Date.Now.Second = 31 _
          Or Date.Now.Minute = 44 And Date.Now.Second = 31 Or Date.Now.Minute = 59 And Date.Now.Second = 31 _
          Then
            'Make Sure Its Supposed To Still Be Running
            If keepRunning Then
              'Make Sure The Process Is Not Already Running
              If Not processing Then
                'Process is not currently running lets start it
                Dim myThread As New Thread(New ThreadStart(AddressOf myProcess))
                myThread.Start()
             End If
            End If
          End If
        End Sub
      
        Public Sub myProcess()
          Try
            ' Set the processing flag so the function does not run again until complete
            processing = True
      
            'Do whatever logic you need here
      
          Catch ex As Exception
            'Since You Can Not Use A MessageBox Do Logging Or Whatever You Need Here
      
          Finally
            processing = False
          End Try
        End Sub
      
      End Class
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 1970-01-01
        相关资源
        最近更新 更多