В .NET являются ли асинхронные методы исключительно теми, которые имеют ключевое слово async?

Здесь говорится о различиях между веб-сокетами и событиями, отправленными сервером. Поскольку Java EE 7 API WebSocket уже входит в спецификацию, и кажется, что отправленные сервером события будут выпущены в следующей версии корпоративного выпуска.

3
задан vpDev 18 January 2019 в 10:15
поделиться

3 ответа

  1. Если метод возвращает Task или Task<T> (за исключением void в случае обработчика события), его можно ожидать и, следовательно, он может быть асинхронным. Ключевое слово async является лишь указанием на то, что оно может await где-то ожидать другого. Основываясь на потоке управления, async может вернуться, фактически ничего не ожидая. Асинхронное программирование не является чем-то новым, оно существует во многих формах, таких как обратные вызовы, вызовы и т. Д.

  2. Примеры, которые вы предоставили, не используют шаблон асинхронного ожидания должным образом. Microsoft предоставила соглашения об именах (Async Suffix) и Task<T>, Task как типы для асинхронного программирования. Поэтому, если вы видите, что какой-то метод возвращает Task<T> или Task, а имя метода имеет суффикс «Async», то вы можете считать его асинхронным. Хотя суффикс не требуется для компилятора, он помогает отличить его от синхронного аналога. (Read против ReadAsync)

  3. Это плохие примеры, эти действия должны быть помечены как асинхронные, и все результаты асинхронных методов следует ожидать для результата. В некоторых консольных программах может быть исключение, когда main не может быть асинхронным.

Пожалуйста, прочитайте Блог Стивена Клири об асинхронном ожидании

0
ответ дан Damien_The_Unbeliever 18 January 2019 в 10:15
поделиться

Асинхронный метод в C # может возвращать void, Task или Task<T>, где вообще следует избегать void, потому что его нельзя ожидать.

Как правило, асинхронные методы должны называться DoSomethingAsync()

Ключевое слово async, однако, является подробностью реализации и не относится к API. Это ключевое слово требуется только в том случае, если вы используете await в теле метода. Но это не обязательно так. Вы можете просто делегировать другому асинхронному методу, без необходимости помечать метод как async и использовать await. ] метод.

В примере он сделал метод синхронно, поставив .Result в конце GetStringAsync

0
ответ дан Creepin 18 January 2019 в 10:15
поделиться

как я могу распознать истинно асинхронные / синхронизирующие методы?

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

Итак, вы можете проверить тип возвращаемого значения метода. Если это void, вы не знаете много. Если это Task, Task<T>, ValueTask<T> или любого другого ожидаемого типа 1 , то метод может быть асинхронным. Но имейте в виду, сигнатура метода может быть исправлена, потому что тип унаследовал метод от базового класса или реализует интерфейс; Таким образом, хотя метод потенциально может быть асинхронным, фактическая реализация этого метода может быть полностью синхронной.

Или, способ может иметь потенциал быть асинхронным, но может иметь определенные потоки управления, которые приводят к тому, что он ведет себя синхронно 2 . Это могут быть, например, что если определенные условия выполняются, у метода уже есть ответ, поэтому он сразу его возвращает. В противном случае он отключается и делает что-то асинхронное - как один из примеров.

Если возвращаемый тип не является ожидаемым и не является пустым, все, что вы можете на самом деле рассуждать о методе, это то, что в точке, в которой он возвращается, ему предоставляется некоторое значение для этого возвращаемого типа 3 . Нет никакого способа рассуждать о какой-либо другой работе , которая могла быть начата этим методом - только то, что, если он сделал что-то подобное, он не намеревается узнать, когда эта работа будет завершена. .


Если вы смотрите на реализацию метода и спрашиваете себя «является ли эта реализация асинхронной», тогда важно выяснить, что делает этот код после того, как элемент управления возвращается обратно. для звонящего.

Когда управление возвращается обратно вызывающей стороне?

  • Когда мы нажимаем return
  • Когда мы нажимаем await, может быть [ 1131]

Когда мы нажимаем await, мы возвращаем управление обратно вызывающему 4 , только если ожидание того, что мы await не завершены еще. Таким образом, мы должны выяснить, откуда появилось это ожидаемое, и, если это произошло из-за вызова другого метода, мы должны начать все заново, чтобы рассмотреть, что делает этот метод.

Если метод содержит await с, то, как правило, безопаснее сказать, что он потенциально асинхронный - но имейте в виду вышеупомянутые возможности относительно уже завершенных ожидаемых и ранних return с.

Если это не async / await, что еще это могло бы сделать? Что ж, если он работает с Task s, он, возможно, создал одну или несколько из этих задач для представления своей текущей работы. Возможно, было запланировано больше кода для запуска через ContinueWith.

Если он не работает с Task напрямую, не вызвал что-то потенциально асинхронное, не вызвало создание нового Thread и не было бесполезно запутано, это, вероятно, [ 1132] синхронно.


Можно ли использовать это в ситуациях, когда, например, у меня очень простой код, и я хочу избежать проблем с многопоточностью / взаимоблокировкой, поскольку я пока не знаком с асинхронным программированием? [1150 ]

Синхронизация по асинхронным шаблонам, показанным в примерах в вашем вопросе, более более склонна к взаимоблокировкам, чем работа с async / await. Зачем? Потому что они блокируют текущий поток в ожидании других событий. Но текущий поток или ресурсы, которые он заблокировал, могут быть особыми - и фактическим асинхронным задачам, которые он вызывает, может потребоваться получить доступ к тому же потоку / ресурсу, прежде чем они смогут завершиться. Классический тупик.


1 Awaitable - одно из многих мест, где C # использует «типизацию утки». Если есть доступный метод (экземпляр или расширение) с именем GetAwaiter, который возвращает тип с правильной формой, это приемлемо. Поэтому, несмотря на тот факт, что вы, вероятно, никогда не увидите его, помните, что пользовательские ожидаемые значения возможны в языке.

2 На ум приходят «горячие пути».

3 И out / ref Параметры. Конечно, если он есть, это не будет асинхронный метод, реализованный через ключевые слова async / await, но он все равно может иметь некоторое асинхронное поведение.

4 Если мы уже передали управление обратно вызывающей стороне во время более раннего await, мы не вернем управление обратно вызывающей стороне позже, но await возвращать это «чему-то», что не является нашим кодом.

0
ответ дан Damien_The_Unbeliever 18 January 2019 в 10:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: