c# - 带有任务数组 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: '索引超出了数组的范围。'
解决方案
我不能在这个例子中循环 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
是什么.
推荐阅读
- python - 如何快速将 S3 存储桶中的 json 文件导入 AWS elasticsearch?
- mysql - Mysql内存不足(需要536870945字节)
- python - 如何通过使用来自实际数据帧的两列中的值索引另一个数据帧来在实际数据帧中创建一列
- c - 使用未定义数量的参数调用 C 函数
- ios - 将 Xcode 调试器附加到在 iOS 模拟器中运行的 Xamarin 应用程序
- haskell - 如何在一定数量的递归调用后停止函数?
- c++ - 错误“lambda 不是从 'std::function' 派生的
- reactjs - 如何修复 NextJS 中的“TypeError:无法读取未定义的属性“id”错误?
- java - 当在同一流管道中使用的终端操作不遵守顺序时,中间操作是否遵守顺序?
- javascript - 如何导航到不在选项卡导航器中的 react native 页面?