Здесь говорится о различиях между веб-сокетами и событиями, отправленными сервером. Поскольку Java EE 7 API WebSocket уже входит в спецификацию, и кажется, что отправленные сервером события будут выпущены в следующей версии корпоративного выпуска.
Если метод возвращает Task
или Task<T>
(за исключением void в случае обработчика события), его можно ожидать и, следовательно, он может быть асинхронным. Ключевое слово async
является лишь указанием на то, что оно может await
где-то ожидать другого. Основываясь на потоке управления, async
может вернуться, фактически ничего не ожидая. Асинхронное программирование не является чем-то новым, оно существует во многих формах, таких как обратные вызовы, вызовы и т. Д.
Примеры, которые вы предоставили, не используют шаблон асинхронного ожидания должным образом. Microsoft предоставила соглашения об именах (Async Suffix) и Task<T>
, Task
как типы для асинхронного программирования. Поэтому, если вы видите, что какой-то метод возвращает Task<T>
или Task
, а имя метода имеет суффикс «Async», то вы можете считать его асинхронным. Хотя суффикс не требуется для компилятора, он помогает отличить его от синхронного аналога. (Read
против ReadAsync
)
Это плохие примеры, эти действия должны быть помечены как асинхронные, и все результаты асинхронных методов следует ожидать для результата. В некоторых консольных программах может быть исключение, когда main не может быть асинхронным.
Пожалуйста, прочитайте Блог Стивена Клири об асинхронном ожидании
Асинхронный метод в C # может возвращать void
, Task
или Task<T>
, где вообще следует избегать void
, потому что его нельзя ожидать.
Как правило, асинхронные методы должны называться DoSomethingAsync()
Ключевое слово async
, однако, является подробностью реализации и не относится к API. Это ключевое слово требуется только в том случае, если вы используете await
в теле метода. Но это не обязательно так. Вы можете просто делегировать другому асинхронному методу, без необходимости помечать метод как async
и использовать await
. ] метод.
В примере он сделал метод синхронно, поставив .Result
в конце GetStringAsync
как я могу распознать истинно асинхронные / синхронизирующие методы?
blockquote>Вы не можете. На самом деле, нет. Вы можете определить методы, которые потенциально являются асинхронными, но мало что можно узнать без ознакомления с документацией или реализацией этих методов.
Итак, вы можете проверить тип возвращаемого значения метода. Если это
void
, вы не знаете много. Если этоTask
,Task<T>
,ValueTask<T>
или любого другого ожидаемого типа 1 sup>, то метод может быть асинхронным. Но имейте в виду, сигнатура метода может быть исправлена, потому что тип унаследовал метод от базового класса или реализует интерфейс; Таким образом, хотя метод потенциально может быть асинхронным, фактическая реализация этого метода может быть полностью синхронной.Или, способ может иметь потенциал быть асинхронным, но может иметь определенные потоки управления, которые приводят к тому, что он ведет себя синхронно 2 sup>. Это могут быть, например, что если определенные условия выполняются, у метода уже есть ответ, поэтому он сразу его возвращает. В противном случае он отключается и делает что-то асинхронное - как один из примеров.
Если возвращаемый тип не является ожидаемым и не является пустым, все, что вы можете на самом деле рассуждать о методе, это то, что в точке, в которой он возвращается, ему предоставляется некоторое значение для этого возвращаемого типа 3 SUP>. Нет никакого способа рассуждать о какой-либо другой работе , которая могла быть начата этим методом - только то, что, если он сделал что-то подобное, он не намеревается узнать, когда эта работа будет завершена. .
Если вы смотрите на реализацию метода и спрашиваете себя «является ли эта реализация асинхронной», тогда важно выяснить, что делает этот код после того, как элемент управления возвращается обратно. для звонящего.
Когда управление возвращается обратно вызывающей стороне?
- Когда мы нажимаем
return
- Когда мы нажимаем
await
, может быть [ 1131]Когда мы нажимаем
await
, мы возвращаем управление обратно вызывающему 4 sup>, только если ожидание того, что мыawait
не завершены еще. Таким образом, мы должны выяснить, откуда появилось это ожидаемое, и, если это произошло из-за вызова другого метода, мы должны начать все заново, чтобы рассмотреть, что делает этот метод.Если метод содержит
await
с, то, как правило, безопаснее сказать, что он потенциально асинхронный - но имейте в виду вышеупомянутые возможности относительно уже завершенных ожидаемых и раннихreturn
с.Если это не
async
/await
, что еще это могло бы сделать? Что ж, если он работает сTask
s, он, возможно, создал одну или несколько из этих задач для представления своей текущей работы. Возможно, было запланировано больше кода для запуска черезContinueWith
.Если он не работает с
Task
напрямую, не вызвал что-то потенциально асинхронное, не вызвало создание новогоThread
и не было бесполезно запутано, это, вероятно, [ 1132] синхронно.
Можно ли использовать это в ситуациях, когда, например, у меня очень простой код, и я хочу избежать проблем с многопоточностью / взаимоблокировкой, поскольку я пока не знаком с асинхронным программированием? [1150 ] blockquote>
Синхронизация по асинхронным шаблонам, показанным в примерах в вашем вопросе, более более склонна к взаимоблокировкам, чем работа с
async
/await
. Зачем? Потому что они блокируют текущий поток в ожидании других событий. Но текущий поток или ресурсы, которые он заблокировал, могут быть особыми - и фактическим асинхронным задачам, которые он вызывает, может потребоваться получить доступ к тому же потоку / ресурсу, прежде чем они смогут завершиться. Классический тупик.
1 sup> Awaitable - одно из многих мест, где C # использует «типизацию утки». Если есть доступный метод (экземпляр или расширение) с именем
GetAwaiter
, который возвращает тип с правильной формой, это приемлемо. Поэтому, несмотря на тот факт, что вы, вероятно, никогда не увидите его, помните, что пользовательские ожидаемые значения возможны в языке.2 sup> На ум приходят «горячие пути».
3 sup> И
out
/ref
Параметры. Конечно, если он есть, это не будет асинхронный метод, реализованный через ключевые словаasync
/await
, но он все равно может иметь некоторое асинхронное поведение.4 sup> Если мы уже передали управление обратно вызывающей стороне во время более раннего
await
, мы не вернем управление обратно вызывающей стороне позже, ноawait
возвращать это «чему-то», что не является нашим кодом.