我刚读了MSDN,发现这里有什么需要建议
http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx
创建委托时,对外部变量n的引用被称为捕获。与局部变量不同,捕获的变量的生命周期会延长,直到引用匿名方法的委托符合垃圾回收的条件。
“捕获”是否意味着它将按值复制? 但是我尝试编写一个示例程序如下:
class Program
{
class async_class
{
private int n = 0;
public async_class()
{
for (int i = 0; i <= 9; i++)
{
System.Console.WriteLine("Outer n={0} address={1}", n, n.GetHashCode());
System.Threading.Thread thread1 = new System.Threading.Thread( () =>
{
System.Console.WriteLine("Inner after n={0} address={1}", ++n, n.GetHashCode());
});
thread1.Start();
//n = 10;
}
}
}
static void Main(string[] args)
{
async_class class1 = new async_class();
}
}
}
在此示例中,内部“++ n”将写回原始外部“n”。结果将是。
外部n = 0地址= 0
外n = 0地址= 0
内部在n = 1地址= 1之后 外n = 1地址= 1
任何人都可以解释有关“捕获”外部变量的更多细节吗?
答案 0 :(得分:4)
不,说它被捕获的全部意义在于它不只是复制值。闭包关闭变量,而不是值。程序中n
的每次访问都访问同一个变量,从来没有任何副本。
那就是说,你的程序是这个案例的一个令人困惑的例子;它正在使用多个线程,这会引入各种竞争条件,因为您无法安全地操纵多个线程中的变量。这将导致各种未定义的行为。如果你想研究闭包,可以从单个线程中学习;它会使你的程序更容易理解,很多。
您可以编写很多更简单的程序来证明闭包关闭变量而不是值。这是一个简单的代码段:
int n = 2;
Action a = () => Console.WriteLine(n);
n = 5;
a();
如果闭包捕获了n
的值,则会打印2.如果它关闭变量而不是值,它将打印5继续运行它,看看会发生什么。