Задачи в массиве - только последний выполняется

Я экспериментировал с задачами. Почему этот вывод 10, а не каждое значение цикла?

public static void StartTasks()
{
    Task[] tasks = new Task[10];
    for (int i = 0; i < 10; i++)
        tasks[i] = new Task(() => Console.WriteLine(i));

    foreach (Task task in tasks)
    {
        task.Start();                       
    }       
}

Ответ 1

С# lambdas фиксирует ссылку на переменную, а не значение переменной.

Если вы хотите захватить значение, вам нужно сделать его копию сначала внутри цикла, что заставляет захват получать ссылку на переменную, меняющуюся локально.

public static void StartTasks()
{
    Task[] tasks = new Task[10];
    for (int i = 0; i < 10; i++) {
        int j = i;
        tasks[i] = new Task(() => Console.WriteLine(j));
    }

    foreach (Task task in tasks)
    {
        task.Start();                       
    }       
}

Ответ 2

В дополнение к принятому ответу вы также можете передать параметр заданию. Например,

    using System;
    using System.Threading.Tasks;

    static void StartTasks(int instances)
    {
        var tasks = new Task[instances];
        for (int i = 0; i < instances; i++)
        {
            tasks[i] = new Task((object param) =>
            {
                var t = (int)param;
                Console.Write("({0})", t);
            }, i);
        }

        Parallel.ForEach<Task>(tasks, (t) => { t.Start(); }); 
        Task.WaitAll(tasks);
    }