问题
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