Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么父任务在其子任务完成之前完成?_C# - Fatal编程技术网

C# 为什么父任务在其子任务完成之前完成?

C# 为什么父任务在其子任务完成之前完成?,c#,C#,在我的代码中,父任务在其子任务之前完成。 为什么会这样 我认为父任务不应该在子任务完成之前完成 我的代码: var parent = Task.Run(() => { int[] tab = new int[3]; new Task(() => { tab[0] = 9; Thread.Sleep(4000); Console.WriteLine("Child1"); }, TaskCreationOp

在我的代码中,父任务在其子任务之前完成。 为什么会这样

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

我的代码:

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
没有线索
Child3 Child2
Child1


因为您没有通过调用
parent.Wait()来等待
parent
任务。有关更多信息,请参阅。具体来说,就是所示的示例。

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

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

可以将块重新写入为:

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();

在任务退出之前是否尝试刷新标准输出?父任务未在其子任务之前完成,但当它完成时,会将stdout刷新到控制台,让它看起来像是孩子们首先完成了什么输出?你期望什么输出以及为什么?我期望:我在这里
Child3
Child2
Child1
9
2
3
线程不足
因为finaltask应该等待父线程,父线程应该等待其子线程完成,而finaltask应该等待父线程完成(“var finalTask=parent.ContinueWith((a)=>{}”),我添加了finalTask.Wait();这会产生您想要的结果吗?