使用不同的参数并行运行相同的代码多次

Mr.*_*Boy 5 c# task

这个非常简单的例子:

        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());
Run Code Online (Sandbox Code Playgroud)

产生:

Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Run Code Online (Sandbox Code Playgroud)

这与预期不同,参数i未正确传递。我曾想过用来Action<int>包装代码,但看不到我会怎么做。我不想写一个专门的方法,就像Task CreateTask(int i)我对如何使用 lambda 感兴趣一样。

执行此操作的正常方法是什么 - 使用不同的参数值并行地多次启动相同的代码?

Pav*_*ski 7

您有一个捕获的循环变量i,尝试在循环内添加临时变量并将其传递给Task

for (var i = 0; i < numLanes; ++i)
{
    var temp = i;
    var t = new Task(() =>
    {
        Console.WriteLine($"Lane {temp}");
    });
    tasks.Add(t);
}
Run Code Online (Sandbox Code Playgroud)

进一步阅读如何在 C# 中捕获变量而不是用脚射击自己foreach循环在 C# 5 之前具有相同的行为,但根据上面的链接

随着 C# 5.0 标准的发布,通过在每次循环迭代中声明迭代器变量来改变这种行为,而不是在编译阶段之前,但对于所有其他结构,类似的行为保持不变,没有任何变化

因此,您可以在foreach没有临时变量的情况下使用


Dav*_*idG 5

您需要捕获for循环内的值,否则所有的Tasks 仍然指的是同一个对象:

for (var i = 0; i < numLanes; ++i)
{
    var innerI = I; // Copy the variable here
    var t = new Task(() =>
    {
        Console.WriteLine($"Lane {innerI}");
    });
    tasks.Add(t);
}
Run Code Online (Sandbox Code Playgroud)

请参阅此处了解更多信息。