在for循环中启动任务:意外行为

本文关键字:意外 任务 启动 for 循环 | 更新日期: 2023-09-27 18:00:14

我正在学习C#中的多线程。这让我很难理解,所以我正在做一些简单的程序来更好地理解它。

我意识到,如果我有:

   static void Main()
    {
        Task[] tasks = new Task[4];
        for (int i = 0; i < 4; i++)
        {
            tasks[i] = Task.Factory.StartNew(() => {
                Console.WriteLine(i);
            });
        }
        Console.ReadKey();
    }

输出是4444,而不是像我预期的0123。为什么?

编辑:

萨迪克在回答中说,这种行为的原因是我正在闭合一个循环变量。但是,如果在lambda语句之外和循环内部将Thread.sleep(500);添加到代码中,则会得到0123。那么,为什么添加这行代码就不会发生这种被认为是由高利贷引起的行为呢?

在我看来,被问及行为的原因似乎是其他原因。如果你不理解我刚刚写的内容,代码是:

static void Main()
    {
        Task[] tasks = new Task[4];
        for (int i = 0; i < 4; i++)
        {
            tasks[i] = Task.Factory.StartNew(() => {
                Console.WriteLine(i);
            });
            Thread.Sleep(500); 
        }
        //Now the output is: 0123
        Console.ReadKey();
    }

在for循环中启动任务:意外行为

制作一个局部变量-将值复制到其中,您应该会得到预期的输出:

static void Main()
{
    Task[] tasks = new Task[4];
    for (int i = 0; i < 4; i++)
    {
        int x = i;
        tasks[x] = Task.Factory.StartNew(() => {
            Console.WriteLine(x);
        });
    }
    Console.ReadKey();
}

获得意外输出的原因是i被共享。您正在结束一个循环变量。