异步编程中参数值的非故意更改-C#

异步编程中参数值的非故意更改-C#,c#,asynchronous,async-await,parameter-passing,C#,Asynchronous,Async Await,Parameter Passing,我正在用C#进行异步编程,并将循环计数器“I”作为参数传递给Task的Run方法,以异步运行它。除了每个任务中的循环计数器“i”在调用者中每次递增时都会更新外,其他一切都正常工作。换句话说,“i”不能保持其值,我不知道如何修复它 //A queue for all the tasks var tasks = new BlockingCollection<Task<ResultWrapper>>(); for (int i = 1; i <= 10; i++) {

我正在用C#进行异步编程,并将循环计数器“I”作为参数传递给Task的Run方法,以异步运行它。除了每个任务中的循环计数器“i”在调用者中每次递增时都会更新外,其他一切都正常工作。换句话说,“i”不能保持其值,我不知道如何修复它

//A queue for all the tasks
var tasks = new BlockingCollection<Task<ResultWrapper>>();
for (int i = 1; i <= 10; i++)
{   
    Console.WriteLine("frame: " + i);
    //Grab a frame
    Bitmap frame = reader.ReadVideoFrame(i);

    //Add the frames to the queue and run them asynchronously
    tasks.Add(Task.Run(() => RequestAnalysis(projectId, endpoint, frame, i))); 
}
以下是一个示例输出:

frame: 1
frame: 2
frame: 3
frame: 4
frame: 5
Frame 3 task is running
Frame 3 task is running
frame: 6
Frame 4 task is running
frame: 7
frame: 8
frame: 9
Frame 5 task is running
frame: 10
Frame 11 task is running
Frame 11 task is running
Frame 11 task is running
Frame 11 task is running
Frame 11 task is running
Frame 11 task is running
但我希望是这样的:

frame: 1
frame: 2
frame: 3
frame: 4
frame: 5
Frame 1 task is running
Frame 2 task is running
frame: 6
Frame 3 task is running
frame: 7
frame: 8
frame: 9
Frame 4 task is running
frame: 10
Frame 5 task is running
Frame 6 task is running
Frame 7 task is running
Frame 8 task is running
Frame 9 task is running
Frame 10 task is running
我将感谢任何帮助。我是C#的新手,我不确定我错过了什么


谢谢。

将lambda绑定到一个不变的变量。例如:

int currentIndex = i;
tasks.Add(Task.Run(() => RequestAnalysis(projectId, endpoint, frame, currentIndex)));

用于任务的lambda表达式捕获变量
i
,而不是
i
的当前值。由于任务在for循环执行时(或之后)开始运行,因此任务会看到当时for循环中/之后
i
的值。解决方案:声明局部变量
var temp=i就在
任务之前。添加(…)
并在lambda表达式中使用
temp
作为参数。(由于在for循环体中声明的
temp
,将为每个for循环迭代重新创建,因此您创建/运行的每个任务都将捕获并查看其各自的
temp
int currentIndex = i;
tasks.Add(Task.Run(() => RequestAnalysis(projectId, endpoint, frame, currentIndex)));