开发者

Windows Service always "Starting" because of infinite loop in OnStart() method

I've written a Windows Service that periodically executes a SSIS package that moves documents from Server A to Server B.

The problem is that in order to do so, I need to use an infinite loop, which starts when the Service starts.

Naturally, I placed this loop into the OnStart() method. Unfortunately, the service never signals that it has started, since it never reaches the end of this method...

Here is the relevant code:

protected override void OnStart(string[] args)
{
    Application app = new Application();
    Package pkg = app.LoadFromDtsServer(@"MSDB\PullD开发者_开发问答oc", "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.
    }
}

I would imagine this is a common problem, given that most Services should be running indefinitely.

Any ideas on how to get this service to return that it has started?

Thanks!


You should use a System.Threading.Timer instead of an infinite loop.


Your service should do its work on a different thread. The OnStart, OnStop etc methods are there to process commands to your service from the Windows Service Control Manager (SCM), and the SCM expects them to return promptly.

Using a System.Threading.Timer as suggested by @SLaks achieves this: the timer events will be executed on a thread from the .NET Thread Pool. Your OnStart method just Enables the Timer, while the OnStop method disables it (OnPause and OnResume can do likewise if you want).


You are not doing this correctly, you should never block a function from returning and you should use a new Thread. As it was suggested, you should use a Timer object. Here is a code snippet to show you how:

    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
    }


I would recommend that you use a System.Threading.Timer like suggested but here is an example of how I would implement the functionality.

In this example I have the function fire 4 times an hour and it will quickly validate if its still running from the previous call and if so skip it otherwise it will create a new thread and fire off the function.

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜