至于本地变量​​传递主题 [英] Regarding local variable passing in Thread

查看:147
本文介绍了至于本地变量​​传递主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有理解的意外输出下面的程序很难:

I'm having a hard time in understanding the unexpected output for the following program:

class ThreadTest
{
     static void Main()
     {
          for(int i = 0; i < 10; i++)
               new Thread(() => Console.Write(i)).Start();
     }

}

查询: 在不同的线程不同的code运行有独立的堆栈?如果是的话,不是变量应preserve它们的值作为int是值类型?

Queries: Different code running in different thread have seperate stacks? If yes, than variables should preserve their values as int is a value type?

推荐答案

每个线程都有自己的堆栈。您所面临的问题无关,与堆栈。问题是,它是产生$ C $下您的匿名委托的方式。使用工具如refelector了解code,它是生成。下面将解决您的问题:

Each thread gets its own stack. The problem that you are facing has nothing to do with stack. The problem is the way it is generating code for your anonymous delegate. Use tool like refelector to understand the code that it is generating. The following will fix your problem:

static void Main() 
        {
            for (int i = 0; i < 10; i++)
            {
                int capture = i;
                new Thread(() => Console.Write(capture)).Start();
            }
        } 

引擎盖下

每当你使用一个变量,从外部范围(在你的情况变量i)在匿名委托,编译器生成一个包装的匿名函数以及它从外部范围使用的数据的新类。因此,在你的情况下产生的类包含 - 一个函数和数据成员捕捉变量i的值。类定义看起来是这样的:

Whenever you use a variable from outer scope (in your case variable i) in anonymous delegate, the compiler generates a new class that wraps anonymous function along with the data that it uses from the outer scope. So in your case the generated class contains - one function and data member to capture the value of variable i. The class definition looks something like:

class SomeClass
{
    public int i { get; set; }

    public void Write()
    {
        Console.WriteLine(i);
    }
}

编译器重新写入你的code如下:

The compiler re-writes your code as follows:

SomeClass someObj = new SomeClass();
for (int i = 0; i < 10; i++)
{
    someObj.i = i;
    new Thread(someObj.Write).Start();
}

,因此问题 - 你正面临着​​。当你捕捉一个变量时,编译器执行以下操作:

and hence the problem - that you are facing. When you capture a variable, the compiler does the following:

for (int i = 0; i < 10; i++)
{
    SomeClass someObj = new SomeClass();
    someObj.i = i;
    new Thread(someObj.Write).Start();
}

请注意在SomeClass的实例化的差异。当你捕捉一个变量,它有迭代次数创建多个实例。如果你不抓住一个变量,它会尝试使用同一个实例的各个版本。

Note the difference in SomeClass instantiation. When you capture a variable, it creates as many instances as there are number of iterations. If you do not capture a variable, it tries to use the same instance for all iterations.

希望,上面的说明会澄清你的疑问。

Hope, the above explanation will clarify your doubt.

感谢

这篇关于至于本地变量​​传递主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆