c# - 从循环启动多个线程时出现 IndexOutOfRangeException
问题描述
Thread[] t = new Thread[threadCount];
int m = 0;
foreach (var thread in t)
{
if (m<threadCount)
{
//This one is needed for paintSingleThread as hight of Bitmap
int height = parts[m].Height;
//this line causes the exception
t[m] = new Thread(() => paintSingleThread(parts[m], "Green", height, width));
t[m].Start();
m++;
}
}
parts[] 是一个已经填充了位图对象的位图数组。我想为不同的线程提供不同的数组成员,但有时我会得到 IndexOutOfRangeException,因为 m 太大了。它不会每次都发生,就像我每隔一次运行程序一样。调试时,每次都很顺利,从未出现过错误。即使如果(米
我对问题的原因和避免此问题的代码更改感兴趣。
解决方案
这段代码
() => paintSingleThread(parts[m], "Green", height, width)
m
通过引用而不是值捕获变量。m
循环完成后的值foreach
将是 threadCount,超出范围。当线程启动得足够快并且 m 在新线程运行您的 lambda 时仍然包含正确的值时,您的代码有时会起作用。出于同样的原因,它可以在调试器中工作。
简单的修复方法:
var part = parts[ m ];
t[ m ] = new Thread( () => paintSingleThread( part, "Green", height, width ) );
此代码会将变量捕获part
到 lambda 中。与m
,不同,part
在循环体内声明。每次循环迭代都会有不同的 实例part
,并且这段代码应该像你期望的那样工作。
推荐阅读
- javascript - 未捕获的 RangeError:进行电子邮件验证时超出最大调用堆栈大小错误
- python - 使用 pyspark 进行条件聚合
- java - 禁止显示错误消息 No entity found for query
- android - RecyclerView 未填充(数组)
- java - 循环数组列表并将匹配两个数组列表的值添加到新列表中
- c# - 获取 Youtube 播放列表中的所有 Youtube 视频,包括其持续时间
- python - 查找两个值的键
- react-native - 未定义不是函数(redux action/react native)
- java - 应用程序默认凭据无法创建 Google App Engine 服务帐户凭据
- html - xpath 条件选择一个节点或另一个节点的文本