Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run same code multiple times in parallel with different parameter

Tags:

c#

task

This very simple example:

        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());

Produces:

Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8
Lane 8

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?

like image 970
Mr. Boy Avatar asked Apr 21 '20 12:04

Mr. Boy


Video Answer


1 Answers

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

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

with the release of the C# 5.0 standard this behavior was changed by declaring the iterator variable inside every loop iteration, not before it on the compilation stage, but for all other constructions similar behavior remained without any changes

So, you may use foreach without temp variable

like image 180
Pavel Anikhouski Avatar answered Oct 19 '22 13:10

Pavel Anikhouski