Task.Run的并行设置数组的值

时间:2016-03-10 08:21:49

标签: c# parallel-processing task

我试图弄清楚这段代码的表现与我的期望不一样。我有一段代码,运行时我希望它会设置数组的每个元素一个不可预测的值,但它设置所有元素具有相同的值。例如期望[1, 32, 0, 1, 32, 3125, ...],但它会产生[32, 32, 32, 32, 32, 32, 32, 32, 32, 32]。为什么呢?

以下是代码:

int l = 1000000;
var mc = new int[10];
var rand = new Random();
var tasks = new Task[l];
for (int i = 0; i < l; i++)
    tasks[i] = Task.Run(() =>
    {
        var r = i % 10;
        mc[0] = r * r * r * r * r; // just to make it run longer
        mc[1] = r * r * r * r * r;
        mc[2] = r * r * r * r * r;
        mc[3] = r * r * r * r * r;
        mc[4] = r * r * r * r * r;
        mc[5] = r * r * r * r * r;
        mc[6] = r * r * r * r * r;
        mc[7] = r * r * r * r * r;
        mc[8] = r * r * r * r * r;
        mc[9] = r * r * r * r * r;
    });

Task.WaitAll(tasks);

EDIT1 据我所知,如果每个任务并行运行,一些线程将尝试同时修改数组,意味着如果线程0修改为mc [5],另一个线程1将尝试修改mc [0],然后mc [0]和mc [5]可能有不同的数字。

1 个答案:

答案 0 :(得分:1)

试试这段代码:

int l = 1000000;
var mc = new int[10000];
var rand = new Random();
var tasks = new Task[l];
for (int i = 0; i < l; i++)
{
    var i2 = i;
    tasks[i2] = Task.Run(() =>
    {
        var r = i2 % 100;
        for (var x = 0; x < 10000; x ++)
        {
            mc[x] = r * r * r * r * r;
        }
    });
}

Task.WaitAll(tasks);

通常,当我输出mc.Distinct()时,我得到了这样的结果:

919965907 
17210368 

我做的两件事是使用i在循环中本地捕获i2,并将mc扩展为10,000个元素。

我甚至得到了7个不同的值。

请记住,您在没有任何锁定的情况下同时修改值,因此您可能会遇到各种竞争条件导致意外值。除了有趣之外,这不是一个好的代码。