Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the correct way to cancel multiple tasks in c#

I have a button thats spawns 4 tasks. The same button changes to a cancel button and clicking this should cancel all 4 tasks. Should I pass the same cancel token to all 4 tasks and have them poll on the same token for IsCancelRequested ? I am confused after reading the msdn doc on createlinkedtokensource. How is this normally done ? thank you

Update: Task.WaitAll() waits tills all tasks complete execution. Similarly how to know when all tasks have been canceled once the shared cancel token source is set to cancel.

like image 946
Gullu Avatar asked Sep 16 '11 21:09

Gullu


People also ask

What is the way to create a task that can be Cancelled after it starts?

Create and start a cancelable task. Pass a cancellation token to your user delegate and optionally to the task instance. Notice and respond to the cancellation request in your user delegate. Optionally notice on the calling thread that the task was canceled.

How do I cancel a CancellationToken?

CancellationToken is immutable and must be canceled by calling CancellationTokenSource. cancel() on the CancellationTokenSource that creates it. It can only be canceled once. If canceled, it should not be passed to future operations.


2 Answers

Yeah, what you said about using a single CancellationToken is correct. You can create a single CancellationTokenSource and use its CancellationToken for all of the tasks. Your tasks should check the token regularly for cancellation.

For example:

const int NUM_TASKS = 4;  CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken ct = cts.Token;  Task[] tasks = new Task[NUM_TASKS]; for (int i = 0; i < NUM_TASKS; i++) {     tasks[i] = Task.Factory.StartNew(() =>     {         while (true)         {             Thread.Sleep(1000);             if (ct.IsCancellationRequested)                 break;         }     }, ct); }  Task.WaitAll(tasks); 

Your button can call cts.Cancel(); to cancel the tasks.

Update for question update:

There are a few ways to do what you ask. One way is to use ct.IsCancellationRequested to check cancellation without throwing, then allow your task to complete. Then Task.WaitAll(tasks) will complete when all of the tasks have been cancelled.

I've updated the code to reflect that change.

like image 143
Matt Avatar answered Oct 23 '22 13:10

Matt


Yes you should pass the same token and use this to cancel all the tasks in one go, if that's your intent.

like image 31
TheCodeKing Avatar answered Oct 23 '22 13:10

TheCodeKing