Parent task does not wait for child task to complete

So here is my code

Task<int[]> parent = Task.Run(() => { var result = new int[3]; TaskFactory tf = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously); for (int i = 0; i < result.Length; i++) { int j = i; tf.StartNew(() => result[j] = GetRandomNumber(j)); } return result; }); var finalTask = parent.ContinueWith(parentTask => { foreach (var i in parentTask.Result) { Console.WriteLine(i); } }); finalTask.Wait(); 

Basically I create 3 Task , which are children of Task called parent (I think). I am considering a parent task in order to wait for the completion of all three child tasks. After that, finalTask will wait for execution due to finalTask.Wait(); of this statemant. But everything is not going as expected. I mean, the application exits before any of the GetRandomNumber calls GetRandomNumber . Part of the code here is copied from a book stating that these parent tasks should wait for the completion of the child task, which apparently does not happen. Did I miss something?

this is what GetRandomNumber does

 public static int GetRandomNumber(int ii) { Random rand = new Random(); for (int i = 0; i < 1000000000; i++) { } // imitate some jobs return rand.Next(1000); } 

This code does the same.

 Task<int[]> parent = Task.Run(() => { var result = new int[3]; for (int i = 0; i < result.Length; i++) { int j = i; new Task(() => result[j] = GetRandomNumber(j), TaskCreationOptions.AttachedToParent).Start(); } return result; }); 
+6
c # task-parallel-library
source share
3 answers

This behavior is due to the use of the Task.Run method, which prevents child tasks from being bound to the parent:

The Run method is a simpler alternative to the StartNew method. It creates a task [whose] CreationOptions value of the TaskCreationOptions.DenyChildAttach property.

To solve, just change the first line from

 Task<int[]> parent = Task.Run(() => 

to

 Task<int[]> parent = Task.Factory.StartNew(() => 
+12
source share

In the documentation for Task.Run, you will find that it points

The property of the CreationOptions property is TaskCreationOptions.DenyChildAttach.

So, although you specify TaskCreationOptions.AttachedToParent , it is ignored.

+8
source share

Please use the code as below:

 static void RunParentTask() { Task<int[]> parent = Task.Factory.StartNew<int[]>(() => { var results = new int[3]; TaskFactory<int> factory = new TaskFactory<int>(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously); factory.StartNew(() => results[0] = 1); factory.StartNew(() => results[1] = 2); factory.StartNew(() => results[2] = 3); return results; }); parent.Wait(); foreach (var item in parent.Result) { Console.WriteLine(item); } } 
+1
source share

All Articles