1

WaitAll not working. I get Done before tasks are completed.

I have some groups. each group contains items i want each item to be processed in a separate task.

static void Main(string[] args) { List<Task> TaskList = new List<Task>(); foreach (string group in groups) { Task task = new Task(() => { scan_group(group, timeout); }); task.Start(); TaskList.Add(task); } Task.WaitAll(TaskList.ToArray()); Console.WriteLine("- Done !" ); } public static void scan_group (){ Task.Factory.StartNew(() => Parallel.ForEach<string>(items, x => { scan(x, y); })); } 
1
  • 1
    Why all this? What real prolem are you trying to solve? All this code except the call to Parallel.ForEach doesn't serve any useful purpose. There's no reason to create cold tasks, especially when you call Start in the very next line. The scan_group method is also weird - it starts a Task and then discards any reference to it, making it impossible to monitor it. Finally, the call to Parallel.ForEach inside another task, just wastes tasks. Commented Dec 17, 2015 at 13:28

2 Answers 2

4

All your scan_group does is start a task without waiting for it to complete, or returning it to be waited for outside.

So you only wait for the internal tasks to be created, you don't wait for them to complete. That's why you get Done before your internal tasks run.

If you want to wait for the scan_group tasks, return them and store them in the list instead of creating tasks using the task constructor. For example:

foreach (string group in groups) { TaskList.Add(Task.Factory.StartNew(() => Parallel.ForEach<string>(items, x => scan(x, y)))); } Task.WaitAll(TaskList.ToArray()); 

Note: Using the Task constructor directly is almost never the right solution. Also Task.Run is preferable to Task.Factory.StartNew if you're on .Net 4.5 and above.

Sign up to request clarification or add additional context in comments.

2 Comments

I suspect it's the groups' elements that need parallel processing, which means all the code could be replaced with a simple Parallel.ForEach call, eg after the group elements get flattened.
@PanagiotisKanavos If the question would have been clearer, I assume it's possible to create a tailor made solution using TPL Dataflow.
0

This is happening because you are not awaiting any tasks. The Task.WaitAll does wait till all your tasks of scan_group() are done. Your scan_group() method however should be an async task.

Inside this method you can then use await on any task you create there. At the moment you are only starting a new task in the scan_group() method but you do not await these tasks. This causes the tasks to be started somewhere on another thread but the thread starting it already moves on and ends the method. The calling method sees this as your task being done.

Some implementation:

Declaration of scan_group():

public static async Task scan_group() { // create tasks for your tasks inside this method. List<Task> itemTasks = new List<Task>(); items.foreach(x => itemTasks.Add(scan(x,y)); await Task.WhenAll(itemTasks.ToArray()); } 

Your call to scan_group would stay the same.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.