C#的Task循环赋值的问题

发布时间 2023-11-27 11:21:10作者: 大大只植物
 static async Task Main(string[] args)
 {
     for (int i = 0; i < 3; i++)
     {
         Task.Run(() => {
            T(i);
         });
        // Thread.Sleep(1);
     }
     Console.ReadLine();
     void T(int i)
     {
         Thread.Sleep(2000);
         Console.WriteLine($"内部:{i}");
     }
 }

上图代码 运行结果是这样的

然后把注释去掉 

 Thread.Sleep(1);

结果是这样的

 出现这样的结果: 应该是这3次循环中, i 指向的内存地址都是一样的,并且task.run里面是异步,它会立刻返回(因此会导致循环结束了,但是task.run里面的其实还没正式开始运行,因此 i 就是最后一次循环的值,那么内部方法T赋值的 i 也是最后一次循环的值,所以呈现出结果都是3).

而加入 Thread.Sleep(1) 可以让执行的时间相对延长一点,导致内部T赋值的 i 有时间可以赋值,所以呈现结果就是0,1,2

 

额外内容: 

  for (int i = 0; i < 3; i++)
  {
      int a = i;
      Task.Run(() => {
         T(a);
      });
      //Thread.Sleep(1);
  }

用一个中间变量赋值,因为此处是值类型是完全复制的,因此不会出现 i 的引用的问题(有点类似js的闭包),以下是结果