Buf*_*run 1 c# lambda multithreading indexoutofboundsexception
当我运行以下代码段时,抛出IndexOutOfRangeException.当抛出异常时,我似乎是2.我的理解是新的线程在i的值被更改之后启动.有没有办法让这段代码免受此类问题的影响?
int x[2] = {1, 3};
int numberOfThreads = 2;
for (int i = 0; i < numberOfThreads; i++)
{
new Thread(() =>
{
DoWork(x[i]);
}).Start();
}
Run Code Online (Sandbox Code Playgroud)
问题是正在捕获变量 i,并且当线程实际开始时,它是2.
请改用:
for (int i = 0; i < numberOfThreads; i++)
{
int value = x[i];
new Thread(() => DoWork(value)).Start();
}
Run Code Online (Sandbox Code Playgroud)
要么:
foreach (int value in x)
{
int copy = value;
new Thread(() => DoWork(copy)).Start();
}
Run Code Online (Sandbox Code Playgroud)
要么:
for (int i = 0; i < numberOfThreads; i++)
{
int copyOfI = i;
new Thread(() => DoWork(x[copyOfI])).Start();
}
Run Code Online (Sandbox Code Playgroud)
在每种情况下,lambda表达式将在循环的每次迭代中捕获一个新变量 - 一个不会被后续迭代更改的变量.
通常,您应该避免在lambda表达式中捕获循环变量,该表达式稍后将执行.有关详细信息,请参阅Eric Lippert关于该主题的博客文章.
从C#5开始,可能foreach会改变循环行为以避免这是一个问题 - 但for循环等效仍然是一个问题.