c# - TaskCreationOptions.AttachedToParent,父任务不等待子任务完成

标签 c# task

考虑以下片段

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/

相关文章:

c# - 在 .Net 中是否有可能在类中的任何方法传递给调用堆栈之前捕获所有未处理的异常?

java - 在 SVN 提交期间运行作业

c# - 将任务转换为任务<T>(包装任务,返回类型为 T)

c# - 长时间运行的任务与线程——性能

c# - 检测父任务取消的正确方法是什么?

unix - Cron 每分每秒运行一次

c# - 在沙箱 AppDomain 中执行反射方法时出现 SecurityException

c# - 迁移者说明(FluentMigrator)?

c# - LINQ 多对多关系 - 获取分组对象的列表

c# - CodedUI 测试更改 URL