问题代码
报错位置在线程上,索引超出数组,但是当我添加断点来单步走的时候反而能正常运行,如果没有加断点就会报错,在线程的那一部分i的数值会变成6
for(int i = 0; i < 5; i++)
{
if (Listen_Port[i] == null || Listen_Port[i].IsAlive == false)
{
Listen_Port[i] = new Thread(() => StartListening(ports[i]));
Listen_Port[i].Start();
}
}
解决方法
在循环中添加局部变量,使用局部变量来索引数组
for(int i = 0; i < ports.Length; i++)
{
int index = i;
if (Listen_Port[index] == null || Listen_Port[index].IsAlive == false)
{
Listen_Port[index] = new Thread(() => StartListening(ports[index]));
Listen_Port[index].Start();
}
}
或者使用foreach来循环数组,foreach循环中的迭代变量是只读的,Lambda 表达式捕获的是每个迭代的值,而不是引用。
关于闭包
闭包是指一个函数可以访问其外部作用域中的变量。 换句话说,闭包允许函数在其定义的作用域之外使用变量。这类问题经常出现在lambda表达式、多线程、循环的场景中。在使用 Lambda 表达式或匿名方法时,由于闭包捕获的是变量的引用,而不是变量的值,因此在循环中可能会导致意外的结果。