c# - 关于在 Thread 中传递的局部变量

标签 c# .net multithreading variables

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

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

}

查询:
在不同线程中运行的不同代码有单独的堆栈?如果是,那么变量应该保留它们的值,因为 int 是一种值类型?

最佳答案

每个线程都有自己的堆栈。您面临的问题与堆栈无关。问题在于它为您的匿名委托(delegate)生成代码的方式。使用反射器之类的工具来理解它正在生成的代码。以下将解决您的问题:

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

引擎盖下

每当您在匿名委托(delegate)中使用外部范围的变量(在您的情况下为变量 i)时,编译器都会生成一个新类,该类将匿名函数及其从外部范围使用的数据包装起来。因此,在您的情况下,生成的类包含 - 一个函数和数据成员来捕获变量 i 的值。类定义类似于:
class SomeClass
{
    public int i { get; set; }

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

编译器按如下方式重写您的代码:
SomeClass someObj = new SomeClass();
for (int i = 0; i < 10; i++)
{
    someObj.i = i;
    new Thread(someObj.Write).Start();
}

因此,您面临的问题是。捕获变量时,编译器会执行以下操作:
for (int i = 0; i < 10; i++)
{
    SomeClass someObj = new SomeClass();
    someObj.i = i;
    new Thread(someObj.Write).Start();
}

注意 SomeClass 实例化的区别。当您捕获一个变量时,它会创建与迭代次数一样多的实例。如果您不捕获变量,它会尝试对所有迭代使用相同的实例。

希望以上解释能澄清你的疑惑。

谢谢

关于c# - 关于在 Thread 中传递的局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8632813/

相关文章:

c# - Biztalk 在 C# 中接收位置

c# - 右键单击时如何聚焦某个标签页?

c# - 解析器错误消息 : Could not create type 'xxx'

.net - ASP.NET 站点地图配置错误

multithreading - 使用 OpenMP 的无用 printf 无法加速

c# - 如何使用 DeviceInformation.FindAllAsync 枚举 Windows Phone 可见的所有 BLE 设备?

c# - 仅当值不为空时如何添加 XAttribute

c# - 如何从 TraceListener 输出中删除进程名称?

python - 多处理速度越慢,进程越多

c# - 在 C# 中运行线程