简体   繁体   中英

Best Practices for dealing with dead worker threads in a .net Windows Service?

I've written a small Windows Service that performs a task at a regular interval. It seems to be working fine, but I have a concern.

The OnStart method starts a "worker thread" that takes on the responsibility of performing the task, waiting for an interval to elapse, and repeating the task.

In the "Windows Services" section of "Administrative Tools", I can set it so that the service restarts automatically if it fails.

However, in the case that the worker thread throws exception, the service appears to continue running. I think that if the worker thread throws exception, the service should be considered stopped, and Windows should take the exception specified in the service settings.

What are the best practices for accomplishing this?

In our case, we don't want a single task to crash the service (since maybe it was just bad data and all the other tasks will complete fine), so we just wrap all the worker logic in a try/catch and log any exception we hit. I do have some exception tracking code that will shut the service down if it's consistently failing though (eg network or database is down).

However, if your service only does a single task and it failing is good cause to stop everything , then I believe writing code to marshal the exception back to the main thread would work. You could save off SynchronizationContext.Current when you start the service, and use it to get back to the main thread when you encounter an exception. I believe that's stop (ehem, crash) the service. Pardon the code if it's not quite right. I don't have VS in front of me at the moment.

void OnStart()
{
  _mainThread = SynchronizationContext.Current();
}

void DoWork()
{
  try
  {
    // Do the stuff...
  }
  catch (Exception e)
  {
    _mainThread.Post(() => Throw);
  }
}

Edit:

On second thought, I think you could accomplish what you want like this... simple :)

(Editted with suggestion in comment from Ishmaeel to use Environment.Exit instead of Stop )

void DoWork()
{
  try
  {
    // Do the stuff...
  }
  catch (Exception e)
  {
    LogException(e);
    Environment.Exit(1);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM