繁体   English   中英

父任务不等待子任务完成

[英]Parent task does not wait for child task to complete

所以这是我的代码

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

    TaskFactory tf = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);

    for (int i = 0; i < result.Length; i++)
    {
        int j = i;
        tf.StartNew(() => result[j] = GetRandomNumber(j));
    }

    return result;
});

var finalTask = parent.ContinueWith(parentTask =>
{
    foreach (var i in parentTask.Result)
    {
        Console.WriteLine(i);   
    }
});

finalTask.Wait();

基本上我创建3个Task ,这种是孩子Task称为父(我猜)。 我要求父任务等待所有三个子任务完成。 之后,由于finalTask.Wait(); finalTask将等待执行finalTask.Wait(); 这个状态。 但事情并没有像预期的那样发生。 我的意思是应用程序在任何GetRandomNumber调用完成之前退出。 这里的代码的某些部分是从书中复制的,该书表明那些父任务应该等待子任务完成,这显然没有发生。 我在这里错过了什么吗?

这就是GetRandomNumber所做的

public static int GetRandomNumber(int ii)
{
    Random rand = new Random();

    for (int i = 0; i < 1000000000; i++) { } // imitate some jobs

    return rand.Next(1000);
}

这段代码做了同样的事情

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

    for (int i = 0; i < result.Length; i++)
    {
        int j = i;
        new Task(() => result[j] = GetRandomNumber(j), TaskCreationOptions.AttachedToParent).Start();
    }

    return result;
});

此行为是由于您使用Task.Run方法,该方法禁止将子任务附加到父级:

Run方法是StartNew方法的简单替代方法。 它创建一个任务[其] CreationOptions属性值为TaskCreationOptions.DenyChildAttach

要解决此问题,只需更改第一行即可

Task<int[]> parent = Task.Run(() =>

Task<int[]> parent = Task.Factory.StartNew(() =>

Task.Run的文档中,您会发现它指定了

其CreationOptions属性值为TaskCreationOptions.DenyChildAttach。

因此,即使您指定了TaskCreationOptions.AttachedToParentTaskCreationOptions.AttachedToParent其忽略。

请使用以下代码:

static void RunParentTask()
    {
        Task<int[]> parent = Task.Factory.StartNew<int[]>(() =>
        {
            var results = new int[3];

            TaskFactory<int> factory = new TaskFactory<int>(TaskCreationOptions.AttachedToParent,
                                                            TaskContinuationOptions.ExecuteSynchronously);
            factory.StartNew(() => results[0] = 1);
            factory.StartNew(() => results[1] = 2);
            factory.StartNew(() => results[2] = 3);

            return results;
        });

        parent.Wait();

        foreach (var item in parent.Result)
        {
            Console.WriteLine(item);
        }
    }

暂无
暂无

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

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