I want to create simple infinite loop which feed the job into task based job pool. Also i would like to limit maximum created tasks at the time (i know that task count does not have to be equal to thread count).
What i have is this:
private readonly HashSet<Task> m_runningTasks = new HashSet<Task>();
private const int QueueTaskCount = 10; //our target task count
.... some method here ....
while (m_run){
IList<Job> jobs = null;
lock(m_runningTasks){
//determine missing job count here
targetCount = QueueTaskCount - m_runningTasks.Count;
if(targetCount>0)
jobs = GetSomeWork(targetCount);
}
if(jobs != null && jobs.Count > 0){
//i want to create jobs here in tasks
foreach(var job in jobs){
var task = new Task(job.Execute);
lock(m_runningTasks)
m_runningTasks.Add(task); //i could add continueTask instead of task here but that does not solve the problem
var continueTask = task.ContinueWith(x=> {lock(m_runningTasks){
m_runningTasks.Remove(x);
} };)
task.Run();
}
Task[] taskArray;
lock(m_runningTasks)
taskArray = m_runningTasks.ToArray()
Task.WaitAny(taskArray).Wait(); //HERE is the problem
}
}
I know that when i create continueWith its a new task but i need to block current thread (which create and execute tasks) till some of its tasks inside m_running collection finish. But when i wait for main tasks they could not be removed from collecition (m_runningTasks) yet because continueTask was not finished.
Also somebody suggested continueWith inside this question: Task does not wait for ContinueWith to finish, but that creates new task and i am not waiting for that, but for the original.
My question is How to remove task from collection inside its action (method) AFTER it is finished.
Example:
Lets have MaxDegreeOfParallelism (Aka QueuTaskCount) = 2
So in first iteration we will launch Tasks A and B both with continuation (which removes A and B from the list) lets call them A' and B'.
So in first iteration we have
A->A'
B->B'
in that line Task.WaitAny() line we wait for tasks
A & B
Lets say that A end and B continue
So we iterate again because that Task.WaitAny is fullfiled and we continue to next iteration
When we count, how many tasks we should create now we do that on this line targetCount = QueueTaskCount - m_runningTasks.Count;
As we said A ended (aka runtocomplettiion) B Running
But in the collection (m_runningTasks) we still might or might not have
A & B Or only B - Depends on the task A' (which removes A from the collection)
and here is the problem. In this itteration i dont know what is the state of the collection - but the correct state is only B because A ended.