【问题标题】:Outer variable captured in Anonymous Methods (lambda)匿名方法 (lambda) 中捕获的外部变量
【发布时间】:2014-03-28 17:02:49
【问题描述】:


我刚刚阅读了 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

谁能解释更多关于“captured”外部变量的细节?

【问题讨论】:

    标签: c# .net lambda


    【解决方案1】:

    不,说它被捕获的全部意义在于它只是复制值。闭包关闭变量,而不是。在您的程序中对n 的每一次访问都在访问同一个变量,永远不会对其进行任何复制。

    也就是说,您的程序是这种情况的一个令人困惑的例子;它使用多个线程,这会引入各种竞争条件,因为您没有安全地从多个线程操作变量。这将导致各种未定义的行为。如果您想研究闭包,请从单个线程中进行;它会让你的程序变得非常、非常、非常更容易推理。

    您可以编写很多更简单的程序来演示闭包关闭变量,而不是值。这是一个简单的sn-p:

    int n = 2;
    Action a = () => Console.WriteLine(n);
    n = 5;
    a();
    

    如果闭包捕获了n 的值,这将打印 2。如果它关闭 变量 而不是它的 ,它将打印 5。运行它,看看会发生什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-01
      • 2019-03-09
      • 2013-12-29
      • 2017-08-14
      • 2012-06-18
      • 2010-10-29
      相关资源
      最近更新 更多