问题描述
这个非常简单的例子:
int numLanes = 8;
var tasks = new List<Task>();
for (var i = 0; i < numLanes; ++i)
{
var t = new Task(() =>
{
Console.WriteLine($"Lane {i}");
});
tasks.Add(t);
}
tasks.ForEach((t) => t.Start());
Task.WaitAll(tasks.ToArray());
产生:
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
这与预期不同,参数 i
未正确传递.我曾想过使用 Action
来包装代码,但不知道我会怎么做.我不想编写像 Task CreateTask(int i)
这样的专用方法,我对如何使用 lambdas 感兴趣.
Which is not as expected, the parameter i
isn't passed correctly. I had thought to use Action<int>
to wrap the code but couldn't see how I would. I do not want to write a dedicated method like Task CreateTask(int i)
I'm interested how to do it using lambdas.
执行此操作的正常方法是什么 - 使用不同的参数值并行运行相同的代码多次?
What is normal way to do this - spin up the same code a bunch of times in parallel with a different parameter value?
推荐答案
您有一个捕获的循环变量 i
,尝试在循环中添加临时变量并将其传递给 任务
You've got a captured loop variable i
, try to add temp variable inside a loop and pass it to the Task
for (var i = 0; i < numLanes; ++i)
{
var temp = i;
var t = new Task(() =>
{
Console.WriteLine($"Lane {temp}");
});
tasks.Add(t);
}
进一步阅读如何在 C# 中捕获变量而不是射中自己.foreach
循环在 C# 5 之前具有相同的行为,但根据上面的链接
Further reading How to capture a variable in C# and not to shoot yourself in the foot. foreach
loop has the same behavior before C# 5, but according to link above
随着 C# 5.0 标准的发布,这种行为被改变了在每次循环迭代中声明迭代器变量,而不是在编译阶段之前,但对于所有其他结构类似的行为保持不变
因此,您可以使用 foreach
而不使用临时变量
So, you may use foreach
without temp variable
这篇关于使用不同的参数并行运行相同的代码多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!