这是我的密码
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);
}以下是GetNum1和GetNum2的定义
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类
class Thing
{
public bool BoolProp { get; set; }
public int IntProp { get; set; }
}基本上,我所做的只是创建Thing对象的集合。然后,我创建了一个单亲任务,它将有几个子任务(我猜,它应该等待)。
有一个number变量,它由子任务以从GetNum1和GetNum2方法(10或3)返回的数量递增。正如我猜的那样,上面的代码应该输出33 (10 + 10 + 10 + 3),但是10被输出,因为等待的只是第一个子任务。如果我把断点放在代码中并一步一步地走,那么输出是正确的。为什么会发生这种事。它必须对父任务中的foreach循环做些什么吗?请不要开始问诸如“你为什么需要这个”和“没有必要”这样的问题,这只是一个例子代码。
发布于 2014-03-01 16:55:36
父任务实际上是等待(而不是“等待”)子任务。您的问题是,代码在没有同步的情况下从多个线程访问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);推荐阅读:Parallel Tasks和Dynamic Task Parallelism。
https://stackoverflow.com/questions/22116846
复制相似问题