asyn c ожидает выполнения кода не так, как ожидалось - PullRequest
1 голос
/ 13 февраля 2020

Я создал простой пример для понимания async / await в C#.

class Program
{
    static void Main(string[] args)
    {
        var t = BarAsync();
        Console.WriteLine("Main");
    }

    private static async Task BarAsync()
    {
        Console.WriteLine("This happens before await");
        int i = await QuxAsync();
        Console.WriteLine("This happens after await. This result of await is " + i);
    }

    private static Task<int> QuxAsync()
    {
        int c = 0;
        for (int i = 0; i < int.MaxValue; i++)
        {
            c++;
        }
        Console.WriteLine("in the middle processing...");
        return Task.FromResult(c);
    }
}

Итак, программа сначала печатает This happens before await, а затем подсчитывает значение из метода возврата. После этого он печатает результат.

image

Выглядит хорошо. Мой вопрос заключается в том, что поскольку await не блокирует поток, который оценивает метод asyn c. Насколько я понимаю, если asyn c займет много времени, он вернется к своему вызывающему методу.

Для моего примера, поскольку QuxAsyn c () занимает много времени, код

Console.WriteLine("Main");

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

 This happens before await
 Main
 in the middle processing...
 This happens after await. This result of await is 2147483647

Однако это не так, почему?

1 Ответ

2 голосов
/ 13 февраля 2020

Я буду вторую (третью?) Рекомендацию других, чтобы вы продолжали читать и узнавать о async. Я неравнодушен к своему собственному async вступлению , но в наши дни есть много хороших.

Мой вопрос заключается в том, что ожидание не блокирует поток, который оценивает метод asyn c. Насколько я понимаю, если asyn c займет много времени, он вернется к своему вызывающему методу.

Это неверная часть. Асинхронность не имеет абсолютно никакого отношения к тому, сколько времени занимает что-то.

Отсутствуют две части знаний, обе из которых описаны в моем async вступлении .

Первое: await работает, сначала проверив его аргумент. Если он уже завершен, то await продолжает выполнение - синхронно .

Второй: каждый метод вызывается синхронно. Включая async методы. Единственная временная асинхронность происходит, когда async метод имеет await, аргумент которого не уже завершен; в этом случае этот метод async возвращает незавершенную задачу.

Соединение их обоих должно объяснить, почему ваш код на самом деле выполняется синхронно.

...