繁体   English   中英

为什么父任务在他的子任务之前完成?

[英]Why parent task finishes before his children tasks?

在我的代码中,父任务在他的子任务之前完成。 为什么会发生?

我认为父任务不应该在子任务完成之前完成。

我的代码:

var parent = Task.Run(() =>
{
    int[] tab = new int[3];

    new Task(() =>
    {
        tab[0] = 9;
        Thread.Sleep(4000);
        Console.WriteLine("Child1");
    }, TaskCreationOptions.AttachedToParent).Start();

    new Task(() =>
    {
        tab[1] = 2;
        Thread.Sleep(2000);
        Console.WriteLine("Child2");
    }, TaskCreationOptions.AttachedToParent).Start();

    new Task(() =>
    {
        tab[2] = 3;
        Thread.Sleep(1000);
        Console.WriteLine("Child3");
    }, TaskCreationOptions.AttachedToParent).Start();

    Console.WriteLine("I am here");
    return tab;
});

var finalTask = parent.ContinueWith((a) =>
{
    a.Result.ToList().ForEach(Console.WriteLine);   
});

finalTask.Wait();
Console.WriteLine("Out of threads");
Console.ReadLine();

结果:

我在这里
9
2
3
线程不足
孩子 3 孩子 2
孩子1

我想,我找到了一个原因:“如果子任务是通过调用Task.Run方法创建的,则父任务会隐式阻止子任务附加到它们。” 所以,我不应该使用Task.Run() ,我应该使用Task.Factory.StartNew()代替。

因为您不是通过调用parent.Wait();等待parent任务parent.Wait(); . 有关更多信息,请参阅附加和分离的子任务 特别是显示的示例。

尽管使用Task.Factory.StartNew()TaskCreationOptions.AttachedToParent选项是将子线程与父线程连接的最佳选择。 但另一种方法可能是在父线程函数中使用Task.WaitAll 唯一的优点是可以使用WaitAll timeout时间。

可以将块重写为:

var parent = Task.Run(() =>
{
    int[] tab = new int[3];

    var child1 = Task.Run(() =>
    {
        tab[0] = 9;
        Thread.Sleep(4000);
        Console.WriteLine("Child1");
    });

    var child2 = Task.Run(() =>
    {
        tab[1] = 2;
        Thread.Sleep(2000);
        Console.WriteLine("Child2");
    });

    var child3 = Task.Run(() =>
    {
        tab[2] = 3;
        Thread.Sleep(1000);
        Console.WriteLine("Child3");
    });

    Task.WaitAll(child1, child2, child3);  //Wait for all 3 threads to complete. 

    Console.WriteLine("I am here");
    return tab;
});

var finalTask = parent.ContinueWith((a) =>
{
    a.Result.ToList().ForEach(Console.WriteLine);
});

finalTask.Wait();
Console.WriteLine("Out of threads");
Console.ReadLine();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM