часть кода до и после задачи ожидания выполняется в том же потоке - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть следующий код в моем проекте консольного приложения:

static void Main()
{
    Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, main");
    var list = new List<Task<int>>();
    for (int i = 1; i < 4; i++)
    {
        list.Add(GetValueAsync(i, i, i));
        //list.Add(GetValueAsync());
    }

    var whenAll = Task.WhenAll(list);
    whenAll.Wait();

    Console.WriteLine(@"End program");
    Console.ReadLine();
}


private static async Task<int> GetValueAsync(int val, int delay, int taskId)
{
    Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{taskId} sleep");

    await Task.Delay(1000 * delay);

    Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{taskId} awake");
    return val;
}

private static int index = 0;
private static async Task<int> GetValueAsync()
{
    index++;
    Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{index} sleep");

    await Task.Delay(2000);

    Console.WriteLine($@"{Thread.CurrentThread.ManagedThreadId}, task{index} awake");
    return 10;
}

когда я использую GetValueAsync с параметрами , я получаю это:

enter image description here

когда я использую GetValueAsync без параметров я получаю это:

enter image description here

Почему часть кода после await Task.Delay(1000 * delay) выполняется в том же потоке, когда я использую GetValueAsync(int val, int delay, int taskId)? если я не ошибаюсь, часть после await должна выполняться в новом потоке ... (текущий проект - консольное приложение, основной поток - не поток GUI)

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

ваши 2 функции имеют разную задержку

первые имеют переменную задержку (1, 2 и 3 с), а вторые имеют постоянную задержку (2 с)

если вы напишите

await Task.Delay(2000); //instead of await Task.Delay(1000 * delay);

у вас будет тот же результат, что и у второй функции

Threadid на самом деле не является инкрементным значением, когда поток завершается, его «id» становится доступным

Тот же ThreadID - это другая задача в вашем случае

0 голосов
/ 01 ноября 2018

На эти вопросы всегда трудно ответить, так как ответы никогда не кажутся удовлетворяющими новичков в теме

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

list.Add(GetValueAsync(i, 1, i));

выход

1, main
1, task1 sleep
1, task2 sleep
1, task3 sleep
5, task2 awake
4, task3 awake
6, task1 awake
End program

Так что не так с первыми результатами? Проще говоря, требуется больше потоков, и обратные вызовы происходят с достаточной задержкой для повторного использования того же потока. Task Scheduler не видит необходимости выделять больше (или другие) ресурсы для вас

...