我在理解AttachedToParent
参数如何工作时遇到问题。AttachedToParent任务混淆
下面是示例代码:
public static void Main(string[] args)
{
Task<int[]> parentTask = Task.Run(()=>
{
int[] results = new int[3];
Task t1 = new Task(() => { Thread.Sleep(3000); results[0] = 0; }, TaskCreationOptions.AttachedToParent);
Task t2 = new Task(() => { Thread.Sleep(3000); results[1] = 1; }, TaskCreationOptions.AttachedToParent);
Task t3 = new Task(() => { Thread.Sleep(3000); results[2] = 2; }, TaskCreationOptions.AttachedToParent);
t1.Start();
t2.Start();
t3.Start();
return results;
});
Task finalTask = parentTask.ContinueWith(parent =>
{
foreach (int result in parent.Result)
{
Console.WriteLine(result);
}
});
finalTask.Wait();
Console.ReadLine();
}
据我了解,当任务有子任务,当所有的子任务准备父任务完成。这个例子的问题是,输出看起来像这样:
0
0
0
这意味着父任务没有等待其子任务完成。得到一个有效的结果0 1 2
的唯一方法是使用等待所有孩子TAKS的,由return results;
语句之前增加了一些一段这样的代码:
Task[] taskList = { t1, t2, t3 };
Task.WaitAll(taskList);
我的问题是这样的。为什么我们在使用TaskCreationOptions.AttachedToParent
时还必须手动为每个子任务调用Wait方法?
编辑:
当我在写这个问题,我已经改变了代码一点点,现在AttachedToParent效果很好。唯一的区别是我用parentTask.Start();
而不是Task.Run();
。
public static void Main(string[] args)
{
Task<int[]> parentTask = new Task<int[]>(()=>
{
int[] results = new int[3];
Task t1 = new Task(() => { Thread.Sleep(3000); results[0] = 0; }, TaskCreationOptions.AttachedToParent);
Task t2 = new Task(() => { Thread.Sleep(3000); results[1] = 1; }, TaskCreationOptions.AttachedToParent);
Task t3 = new Task(() => { Thread.Sleep(3000); results[2] = 2; }, TaskCreationOptions.AttachedToParent);
t1.Start();
t2.Start();
t3.Start();
//Task[] taskList = { t1, t2, t3 };
//Task.WaitAll(taskList);
return results;
});
parentTask.Start();
Task finalTask = parentTask.ContinueWith(parent =>
{
foreach (int result in parent.Result)
{
Console.WriteLine(result);
}
});
finalTask.Wait();
Console.ReadLine();
}
我还是不明白为什么第一个例子有问题。
* DenyChildAttach *真的好像是问题所在。当我创建像这样的父任务:'TaskFactory tf =新的TaskFactory(TaskCreationOptions.DenyChildAttach,TaskContinuationOptions.None); 任务 parentTask = tf.StartNew(()=> {....});'我得到同样的问题,当我使用* TaskCreationOptions.None *时,它工作正常。 –