首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >父任务不等待子任务。

父任务不等待子任务。
EN

Stack Overflow用户
提问于 2014-03-01 16:17:40
回答 1查看 199关注 0票数 4

这是我的密码

代码语言:javascript
复制
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);
}

以下是GetNum1GetNum2的定义

代码语言:javascript
复制
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;
}

下面是Thing

代码语言:javascript
复制
class Thing
{
    public bool BoolProp { get; set; }
    public int IntProp { get; set; }
}

基本上,我所做的只是创建Thing对象的集合。然后,我创建了一个单亲任务,它将有几个子任务(我猜,它应该等待)。

有一个number变量,它由子任务以从GetNum1GetNum2方法(10或3)返回的数量递增。正如我猜的那样,上面的代码应该输出33 (10 + 10 + 10 + 3),但是10被输出,因为等待的只是第一个子任务。如果我把断点放在代码中并一步一步地走,那么输出是正确的。为什么会发生这种事。它必须对父任务中的foreach循环做些什么吗?请不要开始问诸如“你为什么需要这个”和“没有必要”这样的问题,这只是一个例子代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-01 16:55:36

父任务实际上是等待(而不是“等待”)子任务。您的问题是,代码在没有同步的情况下从多个线程访问number变量:

代码语言:javascript
复制
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);

推荐阅读:Parallel TasksDynamic Task Parallelism

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22116846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档