I'm developing a windows service application that uses TPL to start it's main processing task.
The processing task is a continuous while loop that once started, continues it's execution until a cancellation request from Windows Service infrastructure is issued.
The startup is implemented as follows:
protected override void OnStart(string[] args)
{
continuousProcessingTask = Task.Factory.StartNew(
() => DoStuffInAWhileLoopUntilCancelled(cancellation), cancellation,
TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
Question is, I want the service to be terminated if an unhanded exception occurs somewhere in the main task (in DoStuffInAWhileLoopUntilCancelled method).
To be more precise, I want the service to be in a consistent state when unhandled exception occurs in processing task. With the above snippet it will end up with the situation of a running windows service but with processing task terminated, which in my opinion is inconsistent. In my understanding, consistent behavior would mean that a processing task/thread and parent service process are both running, or nothing is running.
I ended up with continuation approach, shutting down service process if the main processing thread has failed:
protected override void OnStart(string[] args)
{
continuousProcessingTask = Task.Factory.StartNew(
() => DoStuffInAWhileLoopUntilCancelled(cancellation), cancellation,
TaskCreationOptions.LongRunning, TaskScheduler.Default)
.ContinueWith(OnTaskCompleted);
}
void OnTaskCompleted(Task task)
{
if (task.IsFaulted)
{
if (task.Exception != null)
{
Service.EventLog.SafeWriteEntry(task.Exception.ToString(), EventLogEntryType.Error);
}
// shut down the application
System.Environment.Exit(-1);
}
}
But I'm not sure if this is a recommended approach here - System.Environment.Exit looks ugly (and breaks class isolation). Are there other options for handling termination of the main processing task in this pattern (first code snippet)?
UPD1: Clarified the question above.
Since expected behavior of service is to run continuously , terminating service in case of exception might not be a good idea. If your app need to perform a certain task a few times, a console app would suffice.
A better approach is to handle exceptions properly(depending on context) and keep the service running. Please note: A running service does not necessarily mean it is performing some task. You can keep the service running and perform task only when needed.
But , if you need to instantly terminate service you can use FailFast .
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.