Внутренние элементы ThreadPoolTaskScheduler - меняет ли порядок параметров Task.WaitAll () порядок выполнения? - PullRequest
0 голосов
/ 17 октября 2018

Я столкнулся с делом, подобным следующему, в моей работе.(Я немного упростил это для целей этого потока)

Вот код (консольное приложение ядра .net):

class Program
{
    static void Main(string[] args)
    {
        const int numberOfTasks = 15;
        var taskArray = new Task[numberOfTasks];

        for (int i = 0; i < numberOfTasks; i++)
        {
            var temp = i;
            taskArray[i] = Task.Run(() => SingleTest(temp));
        }

        Task.WaitAll(taskArray);
        Console.WriteLine("FINISHED!!!");

        Console.ReadKey();
    }

    static void SingleTest(int temp)
    {
        var signal = new AutoResetEvent(false);
        var t1 = Task.Run(() =>
        {
            Console.WriteLine($"{temp} T1 started");
            signal.Set();
            Console.WriteLine($"{temp} T1 finished");
        });

        var t2 = Task.Run(() =>
        {
            Console.WriteLine($"{temp} T2 started");
            signal.WaitOne();
            Console.WriteLine($"{temp} T2 finished");
        });

        Task.WaitAll(t1, t2);
        //Task.WaitAll(t2, t1);
        Console.WriteLine($"{temp}: Both tasks finished");
    }
}

Когда я запускаю этот код с 8 или болееитерации цикла, ни одна из задач T1 не запускается до запуска ВСЕХ задач T2, что кажется странным.Мой вопрос: почему это случилось?Я ожидал, что задачи начнутся в совершенно случайном порядке.

Вот начало вывода для выполнения образца (8 итераций):

5 T2 started
7 T2 started
3 T2 started
0 T2 started
4 T2 started
6 T2 started
2 T2 started
1 T2 started
1 T1 started
1 T1 finished
1 T2 finished
1: Both tasks finished
...

Когда я меняю порядокпараметры в вызове Task.WaitAll () (как в закомментированной строке), поведение совершенно иное, когда задачи запускаются в (на первый взгляд) случайном порядке (большинство задач T1, кажется, запускаются раньше, чем их эквиваленты T2,однако, по крайней мере, некоторые задачи T2 запускаются до того, как все задачи T1 будут выполнены)

Пример вывода:

7 T1 started
5 T1 started
5 T1 finished
4 T1 started
4 T1 finished
1 T1 started
1 T1 finished
6 T1 started
6 T1 finished
3 T1 started
3 T1 finished
1 T2 started --For example,this T2 task was started before some of the T1 tasks
0 T1 started
0 T1 finished
2 T1 started
2 T1 finished
4 T2 started
4 T2 finished
3 T2 started
1 T2 finished
7 T1 finished
0 T2 started
0 T2 finished
2 T2 started
6 T2 started
6 T2 finished
3 T2 finished
1: Both tasks finished

Итак, мне интересно, что происходит под капотомсоздать такое поведение?

...