Slightly generalize and supplement the answer @ i-one. In order to correctly complete the service, you need two things:
- be able to tell the right code that it is time to round out
- wait for this code to complete its execution
You can signal a message in different ways, the most reasonable one is CancellationToken , which is sent to all the necessary code when it starts.
Waiting for completion is also possible in different ways. In the case of streams / synchronous execution, the @ i-one led recipe.
If the application is fully asynchronous (using async/await ), the task is remembered in the startup service and the task is await on the foot.
Another point worth mentioning is that by default, Service Console Manager allocates 30 seconds for the service to terminate (if this value has not been redefined in the registry). If the service did not meet the allotted time, then it is marked in the console as stopped, but the process continues to work, which is not very correct. If the correct completion requires a lot of time, then you can request additional time - up to 125 seconds in total:
protected override void OnStop() { int timeout = 10000; while (!mainTask.Wait(timeout)) { RequestAdditionalTime(timeout); } }
However, in any case, it is useful to have some kind of general timeout (for example, 120 seconds) and to shut down the work forcibly (if suddenly some code is frozen).