我搜索过这个问题,发现很多答案,不难找到解决办法。 但是,我有一个奇怪的经历,不知道原因,所以请人们给我一些建议。 下面是我的代码:
void SetThread()
{
for (int i = 0; i < _intArrayLength; i++)
{
Console.Write(string.Format("SetThread->i: {0}\r\n", i));
_th[i] = new Thread(new ThreadStart(() => RunThread(i)));
_th[i].Start();
}
}
void RunThread(int num)
{
Console.Write(string.Format("RunThread->num: {0}\r\n", num));
}
是的,它们是普通的线程代码。 我希望所有线程数组都应该调用RunThread方法10次。 应该像这样:
SetThread->i: 0
SetThread->i: 1
SetThread->i: 2
SetThread->i: 3
SetThread->i: 4
SetThread->i: 5
SetThread->i: 6
SetThread->i: 7
SetThread->i: 8
SetThread->i: 9
RunThread->num: 0
RunThread->num: 1
RunThread->num: 2
RunThread->num: 3
RunThread->num: 4
RunThread->num: 5
RunThread->num: 6
RunThread->num: 7
RunThread->num: 8
RunThread->num: 9
这就是我期望的结果。顺序不重要。 但我得到的结果如下。
SetThread->i: 0
SetThread->i: 1
SetThread->i: 2
The thread '<No Name>' (0x18e4) has exited with code 0 (0x0).
The thread '<No Name>' (0x11ac) has exited with code 0 (0x0).
The thread '<No Name>' (0x1190) has exited with code 0 (0x0).
The thread '<No Name>' (0x1708) has exited with code 0 (0x0).
The thread '<No Name>' (0xc94) has exited with code 0 (0x0).
The thread '<No Name>' (0xdac) has exited with code 0 (0x0).
The thread '<No Name>' (0x12d8) has exited with code 0 (0x0).
The thread '<No Name>' (0x1574) has exited with code 0 (0x0).
The thread '<No Name>' (0x1138) has exited with code 0 (0x0).
The thread '<No Name>' (0xef0) has exited with code 0 (0x0).
SetThread->i: 3
RunThread->num: 3
RunThread->num: 3
RunThread->num: 3
SetThread->i: 4
RunThread->num: 4
SetThread->i: 5
SetThread->i: 6
RunThread->num: 6
RunThread->num: 6
SetThread->i: 7
RunThread->num: 7
SetThread->i: 8
RunThread->num: 8
SetThread->i: 9
RunThread->num: 9
RunThread->num: 10
我期望RunThread函数可以将参数(num)从0到9传递。但我无法理解错误信息是什么意思。"线程''~~等等。有人能给我一些提示吗?
i
,这个闭包是由传递给ThreadStart
的 lambda 表达式创建的。它们不会在创建Thread
对象时获得当前值的副本,而是在最终调用RunThread
时获取i
的值,这是在启动线程并完成初始化等操作后发生的 - 此时循环将已经进行了一段时间。正如您从输出中看到的那样,这正是发生的情况,RunThread
打印出在SetThread
中看到的最后一个值。 - millimoosevar ii = i;
,并在ThreadStart的参数中使用ii
来防止这种情况发生。这将使lambda表达式关闭不同的局部变量“实例”。(区别在于循环计数器的作用域在循环体外部,是一个局部变量内部。)除非我把JavaScript和C#搞混了。 - millimoose