简体   繁体   中英

Terminating Windows Service in case of exception in processing thread

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.

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