In the snippet below, a task creates two child tasks using the TaskCreationOptions.AttachedToParent, which means the parent task will wait for the child tasks to finish.
Question is - why doesn't the parent task return correct value [102]? Does it first determine its return value and then wait for the child tasks to finish. If so, then what is the point of creating parent-child relationship?
void Main()
{
Console.WriteLine ("Main start.");
int i = 100;
Task<int> t1 = new Task<int>(()=>
{
Console.WriteLine ("In parent start");
Task c1 = Task.Factory.StartNew(() => {
Thread.Sleep(1000);
Interlocked.Increment(ref i);
Console.WriteLine ("In child 1:" + i);
}, TaskCreationOptions.AttachedToParent);
Task c2 = Task.Factory.StartNew(() => {
Thread.Sleep(2000);
Interlocked.Increment(ref i);
Console.WriteLine ("In child 2:" + i);
}, TaskCreationOptions.AttachedToParent );
Console.WriteLine ("In parent end");
return i;
});
t1.Start();
Console.WriteLine ("Calling Result.");
Console.WriteLine (t1.Result);
Console.WriteLine ("Main end.");
}
The output:
Main start.
Calling Result.
In parent start
In parent end
In child 1:101
In child 2:102
100
Main end.
A detached child task is a task that executes independently of its parent. An attached child task is a nested task that is created with the TaskCreationOptions.
Parent Task is a high-level item within task breakdown that is specified with greater detail by a number of related sub-tasks or child tasks. It is the root task that subordinates its sub-tasks and defines how they should be performed and related to each other.
The problem is that you create c1
and c2
as separate tasks but then return i
immediately from t1
before c1
and c2
have incremented i
.
Thus, the return value from t1
is captured at that point, and is still 100
.
As you noted, there isn't much point in a parent/child relationship for this arrangement; but there are plenty of cases where it does make sense.
A common use is just so that the parent task does not complete until its child tasks have completed, but if you require the parent task to wait for its children before returning a value, you will not be able to do it like this.
Of course, you can fix it by adding
Task.WaitAll(c1, c2);
just before the return i;
. I know it's not what you're asking, but I just wanted to point that out anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With