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

天大地大妈咪最大 提交于 2021-01-29 09:49:41

问题


I have created a console app which print the number in a for loop using C# Task.Run() method. If you look at the code, I am initializing the Employee object in the loop and pass the number in the method, though it prints the same number.

Code:

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}");
        }
    }

Output:

The question is- How would I fix this issue? I still want to use Task.Run() method because in my real application scenarios, I want to process the stream (JSON data) in a different thread and do not want to block my main callback method which receive the stream (JSON data).

Thanks in advance.


回答1:


By the time the task actually starts, the value of i has already incremented.

try assigning value of i to another variable and then pass that variable.

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}");
    }
}

Edit: duplicate/source : For Loop result in Overflow with Task.Run or Task.Start




回答2:


This is because lambda capture variables, so they all refer to i, and by the time your task runs the for i is already at 501. You need to store a local variable within your for and copy the current value of i and use that in your lambda so that this specific variable (that is declared within the scope of the loop and thus a new variable each iteration) is the one that is captured

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


来源:https://stackoverflow.com/questions/59540534/why-c-sharp-task-run-method-print-the-same-number-in-the-loop-in-console-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!