Задача асинхронная или синхронная без асинхронного ожидания? - PullRequest
1 голос
/ 01 ноября 2019

Если у меня task без async await, мой task будет считаться асинхронным или синхронным? В Microsoft doc написано The tasks run asynchronously and may complete in any order., но в одном сообщении stackoverflow написано Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete.

1 Ответ

1 голос
/ 01 ноября 2019

Задача асинхронная или синхронная без асинхронного ожидания?

Это зависит полностью от самого Task и будет ничего делать с тем, используете ли вы await или нет.

Когда вы используете Task.Run() для создания новой задачи, она ставит рабочего в очередь в пул потоков, и она будет запускаться асинхронно ,Но вы также можете получить объект Task из метода Task.FromResult(), который тривиально возвращает выполненное задание синхронно .

Между этими двумя крайностями находятся такие вещи, как async методыкоторые иногда завершаются синхронно, а иногда нет (например, чтение данных из файла или сети, где иногда данные уже буферизованы и доступны, а в других случаях они не будут доступны позднее).

* 1025Сообщение о переполнении стека, о котором вы упоминаете , не имеет ничего общего с асинхронным характером задачи, а скорее зависит от того, как вы ждете выполнения задачи. Конечно, синхронно завершенные объекты задачи уже завершены к тому времени, когда у вас есть ссылка на объект, поэтому «ожидание» такого объекта фактически никогда ничего не блокирует. Таким образом, интересным случаем являются объекты задач, которые еще не завершены, т.е. которые будут завершаться асинхронно.

В этих случаях метод Wait() блокирует текущий поток. Это по замыслу и четко задокументировано как таковое. Это почти никогда не то, что вы хотите. Но важно отметить, что даже если вы используете Wait(), сама задача все еще остается асинхронной. Возможно, вы заблокировали текущий поток, но в вашем процессе все еще происходят другие вещи, включая то, что представляет эта задача. Эти вещи происходят асинхронно с вашим текущим потоком.

Тот факт, что вы выбрали, чтобы текущий поток ничего не делал, не меняет по своей сути асинхронный характер задачи, которую вы начали.

Как правило, вы будете использовать await, чтобы эффективно зарегистрировать ваш запрос, чтобы текущий метод возобновил выполнение позже, в текущем контексте синхронизации, после завершения задачи. В операторе await текущий метод возвращает поток обратно вызывающей стороне, позволяя ему продолжать делать другие вещи. В этом случае задача по-прежнему выполняется асинхронно, как если бы вы использовали Wait() и заблокировали поток, но теперь ваш текущий поток также имеет возможность сделать что-то еще.

В обоих случаяхсама задача все еще асинхронная. То, как вы его ждали, никак не влияет на это.

ИМХО, не имеет смысла беспокоиться о том, является ли задача асинхронной или нет. Ваш код должен работать одинаково независимо. Вместо этого рассматривайте задачу как «обещание» обеспечить результат в какой-то момент в будущем. Действительно, слова «обещание» и «будущее» часто используются вместо «задача» в других средах программирования, чтобы представлять одно и то же. Иногда это обещание выполняется немедленно, иногда это занимает некоторое время, но для вас действительно не имеет значения, что произойдет. Важным является само обещание, а не то, как или когда именно оно будет выполнено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...