You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

线程中的内存如何分配?为何C#示例代码线程输出两个t2而非t1和t2

问题根因分析

核心问题是C# Lambda表达式的闭包变量捕获机制和线程调度的异步性共同作用导致的:

  • 你代码中两个Lambda表达式捕获的都是同一个局部变量text,而非Lambda定义时该变量的快照值。也就是说Lambda内部访问的是变量本身的内存地址,不是定义时拷贝的临时值。
  • 调用t1.Start()后线程不会立刻执行,操作系统需要时间调度线程执行。主线程在调用t1的启动方法后会立刻继续向下执行,先完成text = "t2"的赋值操作,等到t1线程真正被调度运行、执行Console.WriteLine(text)时,读取到的text已经是修改后的值t2,最终两个线程输出的都是t2。
修复方案

要解决这个问题,只需要在定义每个Lambda的作用域内新增一个临时局部变量,拷贝当前text的值,让Lambda捕获这个作用域独立的临时变量即可:

class Program 
{
    static void Main()
    {
        string text = "t1";
        // 定义t1专属的临时变量,被Lambda捕获
        string tempForT1 = text;
        Thread t1 = new Thread(() => Console.WriteLine(tempForT1));
        t1.Start();

        text = "t2";
        // 定义t2专属的临时变量,被Lambda捕获
        string tempForT2 = text;
        Thread t2 = new Thread(() => Console.WriteLine(tempForT2));
        t2.Start();
    }
}

注意:修改后仅能保证两个输出的值分别为t1和t2,输出顺序仍可能因为操作系统线程调度的不确定性发生变化,不会固定为先输出t1再输出t2。

内容的提问来源于stack exchange,提问作者Abdullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:15:03