.NET 4.0任务中的私有变量

7

我正在进行一些实验以了解事物的运作方式。我有以下代码...

 for (int i = 0; i < 20; i++)
 {
      Task.Factory.StartNew(() => MethodTest(i));
 }

我想知道为什么MethodTest几乎总是收到int 20(除非我在调试器中逐步执行)。

显然,我的理解有所欠缺,因为我假设当'i'被传递时,它将成为托管线程的本地存储的一部分。

1个回答

15

您正在封闭循环变量 - 请尝试以下方法:

 for (int i = 0; i < 20; i++)
 {
      int x = i;
      Task.Factory.StartNew(() => MethodTest(x));
 }

重要的是要理解,你正在创建一个闭包覆盖变量i,而不是它的当前值。当线程池启动第一个线程(它们首先进入队列)时,变量i几乎肯定是20,因为你已经退出了循环。现在,每个启动的线程将查看变量i在那个时间点的值。建议的解决方法是在循环范围内创建一个新变量,并将变量i的当前值赋给该变量。由于在循环的每次迭代中都使用了一个新变量,因此每个创建的线程现在都在关闭它自己的变量,这是隔离的,不会改变。解释这是什么的标准参考 "Closing over the loop variable considered harmful"。

谢谢,是时候填补一些知识盲点了,之前不知道该往哪里搜索。 :) - RekrowYnapmoc
编辑:作为对未来读者的说明。在C#5中,这将被更改,以便关闭循环变量不需要这个额外的步骤。 - RekrowYnapmoc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接