代码之家  ›  专栏  ›  技术社区  ›  arynaq

TaskCreationOptions.AttachedToParent,父任务未等待子任务完成

  •  1
  • arynaq  · 技术社区  · 8 年前

    考虑以下代码段

    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() 直到孩子们完成?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Damien_The_Unbeliever    8 年前

    因为你打印了 Parent done.. 在内部 父任务。此时,父任务仍在执行,附加的子任务与此无关。

    Task

    附属儿童 不 “任意阻止父任务执行,直到此任务完成”。如果是的话,每一次迭代 for 同样在父任务中运行的循环将被挂起,从而使在循环中创建任务变得毫无意义。

        2
  •  2
  •   nilsK    8 年前

    var task = Task.Factory.StartNew(() =>
    {
        System.Console.WriteLine("Parent starting..");
        var childTasks = new Task[10];
        for (var i = 0; i < 10; ++i)
        {
            childTasks[i] = Task.Factory.StartNew(obj =>
            {
                System.Console.WriteLine($"\tChild #{obj} starting...");
                Thread.Sleep(1000);
                System.Console.WriteLine($"\tChild #{obj} done..");
            }, i, TaskCreationOptions.AttachedToParent);
        }
    
        Task.WaitAll(childTasks);
    });
    
    task.Wait();
    System.Console.WriteLine("Parent done..");
    
    推荐文章