简体   繁体   English

父任务不等待子任务

[英]Child tasks are not awaited by parent task

This is my code 这是我的代码

static void Main(string[] args)
{
    List<Thing> collection = new List<Thing>
    { 
        new Thing { IntProp = 1, BoolProp = true }, 
        new Thing { IntProp = 1, BoolProp = true }, 
        new Thing { IntProp = 2, BoolProp = true }, 
        new Thing { IntProp = 1, BoolProp = false } 
    };

    int number = 0;

    var task = Task.Factory.StartNew<bool>(() =>
    {
        TaskFactory ts = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);

        foreach (var item in collection)
        {
            if (item.BoolProp)
            {
                ts.StartNew(() =>
                    number += GetNum1(item.IntProp));
            }
            else
            {
                ts.StartNew(() =>
                    number += GetNum2(item.IntProp));
            }
        }

        return true;
    });

    task.Wait();

    Console.WriteLine(number);
}

here is are definitions of GetNum1 and GetNum2 这是GetNum1GetNum2定义

static int GetNum1(int num)
{
    for (int i = 0; i < 1000000000; i++) { } // simulate some job

    return 10;
}

static int GetNum2(int num)
{
    for (int i = 0; i < 500000000; i++) { } // simulate some job

    return 3;
}

and here is the Thing class 这是Thing课程

class Thing
{
    public bool BoolProp { get; set; }
    public int IntProp { get; set; }
}

basically what I am doing is just creating the collection of Thing objects. 基本上我正在做的只是创建Thing对象的集合。 then I create a single parent task which will have several child task (which it should await, I guess). 然后我创建一个单一的父任务,它将有几个子任务(它应该等待,我猜)。

there is a number variable which is incremented by child task by the amount returned from GetNum1 and GetNum2 method (10 or 3). 有一个number变量,由子任务递增GetNum1GetNum2方法(10或3)返回的数量。 the code above should output 33 (10 + 10 + 10 + 3) as I guess, but 10 is outputted instead, Because just the first child task is awaited. 我猜测上面的代码应输出33(10 + 10 + 10 + 3),但输出10代码,因为只等待第一个子任务。 If I put the breakpoint in the code and go step by step than the output is correct. 如果我将断点放在代码中并逐步进行,那么输出是正确的。 Why does this happen. 为什么会这样呢? does it have to do something with the foreach loop inside the parent task ? 是否必须对父任务中的foreach循环执行某些操作? Please do not start asking question like "why you need this" and "there is no need for that", this is just an example code. 请不要开始问“为什么需要这个”和“没有必要”这样的问题,这只是一个示例代码。

The parent task is in fact waiting for (not "awaiting") the child tasks. 父任务实际上正在等待(而不是“等待”)子任务。 Your problem is that the code is accessing the number variable from multiple threads without synchronization: 您的问题是代码正在从多个线程访问number变量而没有同步:

var mutex = new object();
int number = 0;

var task = Task.Factory.StartNew<bool>(() =>
{
    TaskFactory ts = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);

    foreach (var item in collection)
    {
        if (item.BoolProp)
        {
            ts.StartNew(() =>
            {
                var value = GetNum1(item.IntProp);
                lock (mutex) number += value;
            });
        }
        else
        {
            ts.StartNew(() =>
            {
                var value = GetNum2(item.IntProp);
                lock (mutex) number += value;
            });
        }
    }

    return true;
});

task.Wait();

lock (mutex)
    Console.WriteLine(number);

Recommended reading: Parallel Tasks and Dynamic Task Parallelism . 推荐阅读: 并行任务动态任务并行

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

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