首页 > 解决方案 > 带有任务数组 IndexOutOfRangeException 的 C# for 循环

问题描述

我开始 10 个任务以从 web api 获取结果。我在偏移数组上得到 IndexOutOfRangeException。但它怎么可能。实际上 'i' 变量不能大于或等于 10。有人可以帮忙吗?For循环不能正常工作?

            times = 10;
            Task[] tasks = new Task[times];
            int[] offsets = new int[times];

            for (int i = 0; i < times; i++)
            {
                offsets[i] = offset;
                tasks[i] = Task.Run(() => SearchLocalByQuery(query, offsets[i], (i + 1)));
                offset += Limit;
            }
            Task.WaitAll(tasks);

我 = 10,

我不能在这个例子中循环 10 次。

System.IndexOutOfRangeException: '索引超出了数组的范围。'

标签: c#for-looptask

解决方案


我不能在这个例子中循环 10 次。

它可以在 lambda 表达式中。这个表达式:

() => SearchLocalByQuery(query, offsets[i], (i + 1))

捕获变量 i,并在执行时评估该变量值。Task.Run立即返回,但不一定已经开始执行委托 - 因此循环完全有可能在i评估之前移动到下一次迭代或完成。

对此的简单解决方法是声明一个局部变量以i在循环内捕获:

for (int i = 0; i < times; i++)
{
    int copy = i;
    offsets[i] = offset;
    // Make sure we only use copy within the lambda expression
    tasks[i] = Task.Run(() => SearchLocalByQuery(query, offsets[copy], copy + 1));
    offset += Limit;
}

现在循环的每次迭代都会有一个新copy变量,并且该变量永远不会改变它的值 - 因此 lambda 表达式将使用“i循环迭代的值”执行,而不管当前的值i是什么.


推荐阅读