10 c#
在这个例子中,我试图通过值传递,但是传递了引用.
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(() => new PhoneJobTest(i);
t.Start();
}
Run Code Online (Sandbox Code Playgroud)
这样可以解决:
for (int i = 0; i < 10; i++)
{
int jobNum = i;
Thread t = new Thread(() => new PhoneJobTest(jobNum);
t.Start();
}
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?为什么原始示例传递引用?
mqp*_*mqp 17
好吧,这就是C#的工作方式.语句中的lambda表达式构造一个词法闭包,i即使在循环结束后,也会存储对该表达式的单个引用.
要解决它,你可以做你做过的事情.
欢迎在网络上阅读有关此特定问题的更多信息; 我的选择将是Eric Lippert在这里的讨论.
Ree*_*sey 16
如果从范围的角度来看待发生的情况,这将更容易理解:
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(() => new PhoneJobTest(i);
t.Start();
}
Run Code Online (Sandbox Code Playgroud)
基本上翻译成非常接近的东西:
int i = 0;
while (i < 10)
{
Thread t = new Thread(() => new PhoneJobTest(i);
t.Start();
i++;
}
Run Code Online (Sandbox Code Playgroud)
当你使用lambda表达式,它使用在lambda之外声明的变量(在你的情况下i),编译器会创建一个叫做闭包的东西 - 一个临时类,它"包装"i变量并将其提供给生成的委托由lambda.
闭包的构造与变量(i)处于同一级别,因此在您的情况下:
int i = 0;
ClosureClass = new ClosureClass(ref i); // Defined here! (of course, not called this)
while (i < 10)
{
Thread t = new Thread(() => new PhoneJobTest(i);
t.Start();
i++;
}
Run Code Online (Sandbox Code Playgroud)
因此,每个Thread都定义了相同的闭包.
当您重新设计循环以使用临时时,将在该级别生成闭包:
for (int i = 0; i < 10; i++)
{
int jobNum = i;
ClosureClass = new ClosureClass(ref jobNum); // Defined here!
Thread t = new Thread(() => new PhoneJobTest(jobNum);
t.Start();
}
Run Code Online (Sandbox Code Playgroud)
现在,每个Thread都有自己的实例,一切正常.
| 归档时间: |
|
| 查看次数: |
3446 次 |
| 最近记录: |