I have the following Loop which may or may not create a series of tasks dynamically:
While(CreateNewTask == true)
{
if(isWorkerFree() && isValidJob() && isExecutable())
{
CancellationTokenSource cs = new CancellationTokenSource();
var myTask = Task.Run(() => Execute(cs.token);
}
}
Now since these tasks are created dynamically, how can I track them and cancel a specific task or send a cancellation token to a specific task? There may be 6-7 tasks running at any time, I need the functionality to know which ones are running and cancel a specific one.
You can track each such task using a DTO:
class Item { Task Task; CancellationTokenSource CTS; }
. Keep a list of those items. You can then cancel them at will.TL;DR;
I think that the TPL Dataflow (https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx) is a better choice here but I will answer using the TPL
Answer
To limit the concurrency, what you need is a scheduler that limits concurrency. I suggest that you look at https://msdn.microsoft.com/library/system.threading.tasks.taskscheduler.aspx and search for LimitedConcurrencyLevelTaskScheduler.
The code below is a simple example of what you are trying to achieve.
This will generate the following log
You can see that the Task 0 is cancelled as soon as possible and Task 1 continue to process. This example does not show but will never be more than 7 concurrent tasks.
Unfortunately the TAP pattern does not works with the AttachToParent option of the Scheduler, or this code could be even more clean. See: TaskCreationOptions.AttachedToParent is not waiting for child task
And to manage the CancellationTokens you can create a specific TaskFactory that allows something like this:
None of the TaskFactory methods are virtual so you will have to create overloaded method.