c#的windows service 为什么需要线程,老外的解释?

The first time I wrote a service, I wondered whether we could do something like Listing 4, rather than go to the trouble of adding a timer. (注:我也是这么想的)

Listing 4 The unstoppable service.

protected override void OnStart(string[] args)
{
   while (true)
   {
      // do some work
 
      // idle
      Thread.Sleep(0, interval, 0)
   }
}

I soon realized that the service appears to be hung if I did this. When you start the service, Windows won't get feedback that the service has started, since the service blocks in the OnStart call. Windows will promptly report an appropriate error. Another catch is that you can't tell the service to stop, because it never leaves the OnStart event!

But we can do something similar to achieve our objective of a periodic invocation of the worker method: We use a separate thread. Let's start by declaring some class-level variables, as shown in Listing 5. (讲的很清楚了,不解释)

Listing 5 Class-level variables for the single-thread approach.

// This is a flag to indicate the service status
private bool serviceStarted = false;
 
// the thread that will do the work
Thread workerThread;
...

Listing 6 shows the matching OnStart.

Listing 6 OnStart method for the single-thread approach.

protected override void OnStart(string[] args)
{
   // Create worker thread; this will invoke the WorkerFunction
   // when we start it.
   // Since we use a separate worker thread, the main service
   // thread will return quickly, telling Windows that service has started
   ThreadStart st = new ThreadStart(WorkerFunction);
   workerThread = new Thread(st);
 
   // set flag to indicate worker thread is active
   serviceStarted = true;
 
   // start the thread
   workerThread.Start();
}

The code in Listing 6 instantiates a separate thread and attaches our worker function to it. Then it starts the thread and lets the OnStart event complete, so that Windows doesn't think the service is hung.

Listing 7 shows the code for the worker function.

Listing 7 Worker method for the single-thread approach.

/// <summary>
/// This function will do all the work
/// Once it is done with its tasks, it will be suspended for some time;
/// it will continue to repeat this until the service is stopped
/// </summary>
private void WorkerFunction()
{
   // start an endless loop; loop will abort only when "serviceStarted"
   // flag = false
   while (serviceStarted)
   {
      // do something
      // exception handling omitted here for simplicity
      EventLog.WriteEntry("Service working",
         System.Diagnostics.EventLogEntryType.Information);
 
      // yield
      if (serviceStarted)
      {
         Thread.Sleep(new TimeSpan(0, interval, 0);
      }
   }
 
   // time to end the thread
   Thread.CurrentThread.Abort();
}

The function will go into an endless loop until the serviceStarted parameter is false. The parameter itself will be set to false in the OnStop event shown in Listing 8.

Listing 8 OnStop method for the single-thread approach.

protected override void OnStop()
{
   // flag to tell the worker process to stop
   serviceStarted = false;
 
   // give it a little time to finish any pending work
   workerThread.Join(new TimeSpan(0,2,0));
}

Note that we provide a reasonable amount of time to the worker thread (two minutes in Listing 8) to complete its work. But if it doesn't complete within that time, the workerThread.Join clause will terminate it.