即使在方法完成后线程如何访问局部变量?

Pra*_*lla 10 c# multithreading

说我有这样的C#方法

public void MyMethod()
    {
        int i = 0;

        var thread = new Thread(() =>
        {
            Thread.Sleep(100);

            if (i == 0)
            {
                Console.WriteLine("Value not changed and is {0}", i);
            }
            else
            {
                Console.WriteLine(" Value changed to {0}.", i);
            }
        });

        thread.Start();


        i = 1;
    }
Run Code Online (Sandbox Code Playgroud)

这里的方法创建一个访问方法中创建的局部变量的线程.到访问此变量时,方法已完成,因此不应存在局部变量i.但代码运行没有任何麻烦.根据我的理解,方法块完成后局部变量不存在.我无法得到它.

Ree*_*sey 15

这是有效的,因为编译器会重写您的代码以使用闭包.

由于您在lambda中使用变量,因此变量最终会更改为类的成员.编译后的代码不包含i的局部变量 - 即使你是这样编写的.相反,它重写您的代码以使用包含Int32作为成员变量的编译器生成的类,而"本地代码"以及lambda则引用此类成员.

有关详细信息,请参阅此关于闭包的博客文章,该文章让您粗略了解编译器在此处执行的操作.


Eri*_*ert 5

根据我的理解,方法块完成后局部变量不存在.我无法得到它.

你的理解是完全错误的.局部变量的定义特征是其名称仅在其声明块内的范围内.这就是为什么它被称为"本地"变量 - 因为它的名称只在本地可见.

你相信"本地"的意思是"短暂的".那是不对的; 本地变量可以是短暂的,但有三种情况不可能:当它是匿名函数的封闭外部变量时,当它在迭代器块中时,或者当它在异步块.

巧合的是,你的问题是我上周博客的主题; 看到它了解更多细节:

http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx