考虑以下片段
var task = Task.Factory.StartNew(() =>
{
Console.WriteLine("Parent starting..");
for (var i = 0; i < 10; ++i)
Task.Factory.StartNew(obj =>
{
Console.WriteLine($"\tChild #{obj} starting...");
Thread.Sleep(1000);
Console.WriteLine($"\tChild #{obj} done..");
}, i, TaskCreationOptions.AttachedToParent);
Console.WriteLine("Parent done..");
});
task.Wait();
哪些输出
Parent starting..
Parent done..
Child #0 starting...
Child #2 starting...
Child #9 starting...
Child #5 starting...
Child #1 starting...
Child #6 starting...
Child #4 starting...
Child #3 starting...
Child #7 starting...
Child #0 done..
Child #1 done..
Child #8 starting...
Child #6 done..
Child #3 done..
Child #5 done..
Child #4 done..
Child #9 done..
Child #2 done..
Child #7 done..
Child #8 done..
这怎么可能?文档明确指出 StartNew
(在父级上)具有默认创建选项,这不会拒绝子级附加到它。
为什么父级上的 task.Wait()
不阻塞直到子级完成?
最佳答案
因为您从父任务内打印Parent done..
。此时,父任务仍在执行,附加的子任务无关紧要。
只有当任务代码将控制权返回给 TPL 时,它才会考虑是否附加了任何子级,因此是否将 Task
对象标记为完成。
附属的 child 不会“任意阻止父任务执行,直到该任务完成”。如果是,则同样在父任务中运行的 for
循环的每次迭代都将被挂起,并使在循环中创建任务变得毫无意义。
关于c# - TaskCreationOptions.AttachedToParent,父任务不等待子任务完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52850832/