为什么 C# Task.Run() 方法在控制台应用程序的循环中打印相同的数字?

Why C# Task.Run() method print the same number in the loop in console app?

我创建了一个 控制台应用程序 ,它使用 C# Task.Run() 方法在 for 循环中打印数字。如果您查看代码,我会在循环中初始化 Employee object 并在方法中传递数字,尽管它打印相同的数字。

代码:

class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 500; i++)
            {
                Task.Run(() => new Employee().ProcessEmployee(i));
            }
            Console.Read();
        }
    }

    public class Employee
    {
        public void ProcessEmployee(int employeeId)
        {
            Console.WriteLine($"The number is: {employeeId} and thread is {Thread.CurrentThread.ManagedThreadId}");
        }
    }

输出:

问题是- 我该如何解决这个问题?我仍然想使用 Task.Run() 方法,因为在我的实际应用场景中,我想在不同的线程中处理流(JSON 数据)并且不想阻塞我接收流的主要回调方法(JSON 数据)。

提前致谢。

任务实际开始时,i的值已经递增。

尝试将 i 的值分配给另一个变量,然后传递该变量。

class Program
{
    static void Main(string[] args)
    {
        for (int i = 1; i <= 500; i++)
        {
            int j = i;
            Task.Run(() => new Employee().ProcessEmployee(j));
        }
        Console.Read();
    }
}

public class Employee
{
    public void ProcessEmployee(int employeeId)
    {
        Console.WriteLine($"The number is: {employeeId} and thread is {Thread.CurrentThread.ManagedThreadId}");
    }
}

编辑:duplicate/source:

这是因为 lambda 捕获变量,所以它们都引用 i,当您的任务运行时,for i 已经在 501。您需要在其中存储一个局部变量您的 for 并复制 i 的当前值并在您的 lambda 中使用它,以便这个特定变量(在循环范围内声明,因此每次迭代都是一个新变量)是被捕获的变量

for(int i = ....)
{
    var tmp = i;
    Task.Run(() => new Employee().ProcessEmployee(tmp));
}