Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tracking completed/running System.Threading.Tasks.Task objects

Tags:

c#

.net

I am writing a Windows Service that receives messages/requests and executes them asynchronously - it does not need to wait for the item to complete, nor care about the result. I am successfully able to execute the requests as Tasks using System.Threading.Tasks.Task. Most of these items execute quickly (less than a second), but some take longer (2-3 minutes).

As a windows service, I need to respond to the "Stop" command and some of the Tasks will still be running. It is preferable to not Cancel the Tasks as the longer running ones might leave data in a bad state (and a rollback is very tricky).

What is the best way to handle this? I thought of keeping a List of the tasks that I have started so that I can do a WaitAll. During the execution of the service it will process tens of thousands of requests. How would I know when to remove completed Tasks from the List so the List doesn't grow wildly? I don't think I should be holding references to that many Task objects.

Thanks in advance.

like image 271
ronrock00 Avatar asked Apr 30 '26 20:04

ronrock00


1 Answers

You can use CancellationToken for this purposes. Once OnStop event occured, you just call method Cancel() on the CancellationTokenSource and it will be propagated to all tasks that you passed the token in. There are several techniques how to correctly cancel a task. You may explicitly check from time to time inside the task if cancellation requested. Or I beleive there is a property ThrowWhenCancelled on a token itself, and if cancellation has been requested token will throw an CancellationException.

If you don't care about the task results, but want to have a tracking list, just keep the List<Task<T>> (or may be ConcurrentBag<Task<T>>)as a local variable. From time to time start another task that will go through the list and check the Task.Status property, if it's running or else.

I don't think keeping that many references should be an issue as long as you maintain those references correctly. Also, it depends how do you want to stop your application. If you are fine with the task being killed along with the application you may not track them (unless they hold some resources to hold, and you need to free them) at all. But in most of the cases I would say it should be correctly finalized.

EDIT: just reread your post. RequestAdditionalTime call may help you to wait until long runnning tasks are finished. Check it on MSDN: ServiceBase.RequestAdditionalTime Method

like image 153
paulik Avatar answered May 03 '26 09:05

paulik