Ответ 1
Извините, если это глупый вопрос
Это не глупый вопрос. Это важный вопрос.
У меня есть коллега, который утверждает, что это делает вызов A синхронным, и он продолжает придумывать журналы Console.WriteLine, которые, по-видимому, подтверждают его точку зрения.
Это фундаментальная проблема, и вам нужно обучить своих коллег, чтобы они перестали вводить в заблуждение себя и других. Асинхронного вызова не существует. Вызов не является асинхронным, никогда. Скажи это со мной. Вызовы не асинхронные в С#. В С# при вызове функции эта функция вызывается сразу после вычисления всех аргументов.
Если ваш коллега или вы считаете, что существует такая вещь, как асинхронный вызов, вас ждет мир боли, потому что ваши убеждения о том, как работает асинхронность, будут очень оторваны от реальности.
Итак, ваш коллега прав? Конечно они есть. Вызов A
является синхронным, поскольку все вызовы функций являются синхронными. Но тот факт, что они считают, что существует такая вещь, как "асинхронный вызов", означает, что они сильно ошибаются в отношении того, как асинхронность работает в С#.
Если конкретно ваш коллега считает, что await M()
каким-то образом делает вызов M()
"асинхронным", то у вашего коллеги есть большое недоразумение. await
является оператором. Конечно, это сложный оператор, но это оператор, который работает со значениями. await M()
и var t = M(); await t;
- это одно и то же. Ожидание происходит после вызова, потому что await
работает с возвращаемым значением. await
- это НЕ инструкция для компилятора для "генерации асинхронного вызова M()" или чего-либо подобного; нет такого понятия, как "асинхронный вызов".
Если это характер их ложного убеждения, тогда у вас есть возможность обучить своего коллегу тому, что означает await
. await
означает что-то простое, но мощное. Это значит:
- Посмотрите на
Task
, над которым я работаю. - Если задача выполнена исключительно, выведите это исключение
- Если задача выполнена нормально, извлеките это значение и используйте его
- Если задача не выполнена, зарегистрируйте оставшуюся часть этого метода как продолжение ожидаемой задачи и верните моему вызывающему новый
Task
, представляющий этот незавершенный асинхронный рабочий процесс этого вызова.
Это все, что await
делает. Он просто проверяет содержимое задачи, и, если задача не завершена, он говорит: "Ну, мы не можем добиться какого-либо прогресса в этом рабочем процессе, пока эта задача не будет завершена, поэтому вернитесь к моей вызывающей стороне, которая найдет что-то еще для этого ЦП. делать ".
природа кода внутри A не меняется только потому, что мы его не ждем.
Это правильно. Мы синхронно вызываем A
, и он возвращает Task
. Код после вызова сайта не выполняется, пока не вернется A
. Интересная вещь в A
заключается в том, что A
разрешено возвращать неполный Task
вызывающей стороне, и эта задача представляет узел в асинхронном рабочем процессе. Рабочий процесс уже асинхронный, и, как вы заметили, для A
не имеет значения, что вы делаете с его возвращаемым значением после его возвращения; A
не знает, собираетесь ли вы await
вернуть Task
или нет. A
просто выполняется так долго, как может, и затем либо возвращает завершенную обычно задачу, либо завершенную исключительно задачу, либо возвращает незавершенную задачу. Но то, что вы делаете на сайте вызовов, не меняет этого.
Поскольку возвращаемое значение из A не требуется, нет необходимости ждать задачи на сайте вызова
Правильно.
нет необходимости ждать задачи на сайте вызова, пока кто-то в цепочке ожидает ее (что происходит в C).
Теперь ты потерял меня. Почему кто-то должен ждать Task
, возвращенного A
? Скажите, почему вы считаете, что кто-то должен await
это Task
, потому что у вас может быть ложное убеждение.
Мой коллега очень настойчив, и я начал сомневаться в себе. Мое понимание неверно?
Ваш коллега почти наверняка не прав. Ваш анализ кажется правильным вплоть до того момента, когда вы говорите, что существует требование, чтобы каждый Task
был await
издан, что не соответствует действительности. Странно не await
a Task
, потому что это означает, что вы написали программу, в которой вы начали операцию, и не заботитесь о том, когда или как она завершается, и, конечно, плохо писать такую программу, но не является требованием к await
каждому Task
. Если вы верите, что есть, снова скажите, что это за убеждение, и мы разберемся с ним.