Async: почему AsyncDownloadString? - PullRequest
       1

Async: почему AsyncDownloadString?

1 голос
/ 08 июля 2011

Хорошо ... Я немного запутался здесь. Монада async позволяет вам использовать let!, который запустит вычисление данного асинхронного метода и приостановит поток, пока результат не станет доступным. Это все хорошо, я понимаю, что.

Теперь я не понимаю, почему они создали расширение для класса WebClient с именем AsyncDownloadString. Не могли бы вы просто обернуть обычный DownloadString внутри асинхронного блока? Я почти уверен, что здесь упущен важный момент, так как я провел некоторое тестирование, которое показывает, что DownloadString, заключенная в асинхронный блок, по-прежнему блокирует поток.

Ответы [ 2 ]

6 голосов
/ 08 июля 2011

Существует важное различие между ними:

  • Метод DownloadString является синхронным - поток, который вызывает метод, будет заблокирован до тех пор, пока не будет загружена вся строка (т.е. довесь контент передается через Интернет).

  • С другой стороны, AsyncDownloadString не блокирует поток в течение длительного времени.Он просит операционную систему начать загрузку, а затем освобождает поток.Когда операционная система получает некоторые данные, она выбирает поток из пула потоков, поток сохраняет данные в некотором буфере и снова освобождается.Когда все данные загружены, метод считывает все данные из буфера и возобновляет остальную часть асинхронного рабочего процесса.

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

Внутри метод AsyncDownloadString является просто оболочкой для DownloadStringAsync, так что вы также можете найти больше информации в документации MSDN .

3 голосов
/ 08 июля 2011

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

Если вы посмотрите на различные классы ввода-вывода в .NET, такие как File, Socket и т. Д. Все они имеют блокирующие, а также неблокирующие операции чтения и записи.Операции блокирования будут ожидать завершения ввода-вывода в потоке ЦП и, следовательно, блокирования потока ЦП до завершения ввода-вывода, при этом в качестве неблокирующих операций используются перекрывающиеся вызовы API-интерфейса ввода-вывода для выполнения операции.

У Async есть метод, позволяющий сделать асинхронный блок из этих неблокирующих API-интерфейсов файлов, сокетов и т. Д. В вашем случае вызов DownloadString заблокирует поток ЦП, поскольку он использует API-интерфейс блокировки базового класса, где как AsyncDownloadString использует API-интерфейс без блокировки - io с перекрытием.

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