Parallel of Task.Run 设置数组的值



我试图弄清楚这段代码的行为不符合我的预期。我有一段代码,当运行时,我希望它会用不可预测的值设置数组的每个元素,但它会用相同的值设置所有元素。例如,期望[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);

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

试试这段代码:

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 

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

有一次我什至得到了 7 个不同的值。

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

最新更新