In this example I’m showing the launching of further tasks within an existing task.
The Main method launches a single task (of course, it would likely be many tasks in a real system) which is implemented by MainTask and then waits for that task to complete. The MainTask then launches many independent tasks (impelemnted as SubTask and attaches each of them to the parent task (in this case MainTask). This has the effect that when MainTask ends the code in Main is still blocked at the Wait call until all the child tasks have also completed.
Code Example
class Program
{
static void Main(string[] args)
{
Task t = Task.Factory.StartNew(MainTask);
t.Wait();
Console.WriteLine("Program finished");
Console.ReadLine();
}
public static void MainTask()
{
Console.WriteLine("Starting the Main Task");
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Task.Factory.StartNew(SubTask, TaskCreationOptions.AttachedToParent);
Console.WriteLine("Ending the Main Task");
}
public static void SubTask()
{
Console.WriteLine("Starting SubTask {0}", Task.CurrentId);
Thread.Sleep(2500);
Console.WriteLine("Ending SubTask {0}", Task.CurrentId);
}
}
Output
Starting the Main Task Ending the Main Task Starting SubTask 1 Starting SubTask 2 Starting SubTask 3 Starting SubTask 4 Starting SubTask 5 Starting SubTask 6 Ending SubTask 2 Starting SubTask 7 Ending SubTask 1 Starting SubTask 8 Ending SubTask 3 Starting SubTask 9 Ending SubTask 4 Starting SubTask 10 Ending SubTask 5 Ending SubTask 6 Ending SubTask 7 Ending SubTask 8 Ending SubTask 9 Ending SubTask 10 Program finished
See also
I have also writtent a blog post on Tasks that create more work which may give further insight into this area.


This example is useless because it should not need the sleep to finish all tasks, except it does because attach to parent is vague and doesn’t work as expected. If the tasks do not finish before the sleep is done they are aborted!!!
The sleep is not required. The sleep is only there so that I didn’t have to code an actual long-ish running task. It is there to simulate a task that takes an amount of time to run. That’s all.
I’m not sure that AttachToParent is vague and doesn’t work as expected. You’ll have to provide an example and explain what you expect to happen and what actually does happen. I tried my example above without the Sleep statement (as I said, it was a contrivance so I didn’t have to write actual long running code) and it all worked as expected. Here is the output: