Почему я должен использовать асинхронную операцию вместо синхронной? - PullRequest
5 голосов
/ 14 декабря 2011

Я всегда размышлял об этом.

Допустим, у нас есть простой асинхронный веб-запрос с использованием класса HttpWebRequest

class webtest1
{
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("www.google.com");

    public webtest1()
    {
        this.StartWebRequest();
    }

    void StartWebRequest()
    {
        webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
    }

    void FinishWebRequest(IAsyncResult result)
    {
        webRequest.EndGetResponse(result);
    }
}

То же самое можно легко достичь с помощью синхронной операции:

class webtest1
{
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("www.google.com");

    public webtest1()
    {
        webRequest.GetResponse();
    }
}

Так почемуя хотел бы использовать более запутанную асинхронную операцию, когда достаточно более простой операции синхронизации?Для экономии системных ресурсов?

Ответы [ 6 ]

9 голосов
/ 14 декабря 2011

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

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

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

6 голосов
/ 14 декабря 2011

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

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

6 голосов
/ 14 декабря 2011

Синхронная операция не позволит вам делать что-либо еще в ожидании завершения запроса или истечения времени ожидания.Использование асинхронной операции позволит вам анимировать что-то для пользователя, чтобы показать, что программа занята, или даже позволить им продолжать работу с другими областями функциональности.

4 голосов
/ 14 декабря 2011

Асинхронность становится особенно полезной, когда у вас происходит больше вещей, чем у ядер - например, у вас может быть несколько активных веб-запросов, несколько операций доступа к файлу, несколько вызовов БД и, возможно, некоторые другие сетевые операции. (WCF или Redis может быть). Если все это синхронно, вы создаете много потоков, много стеков и много переключений контекста. Если вы можете использовать асинхронный API, вы обычно можете использовать потоки пула в течение коротких моментов, когда каждая операция выполняет что-то. Это отлично подходит для высокопроизводительных серверных сред. Наличие нескольких ядер - это здорово, но быть эффективнее - лучше.

В C # 5 через await это становится не более трудоемким, чем ваш второй пример.

2 голосов
/ 14 декабря 2011
1 голос
/ 14 декабря 2011

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

2) У вас много вызовов, обработка которых занимает много времени. Зачем блокировать весь потоккогда это может продолжаться и делать другие вещи в ожидании возвращения?Например, если у меня есть пять вызовов функций, каждый из которых занимает 5 секунд, я хотел бы сразу запустить их все и вернуть их при необходимости.

3) Слишком много данных для обработки на выходе синхронно.Если у меня есть программа, которая записывает 10 гигабайт данных на консоль, и я хочу прочитать вывод, у меня есть возможность асинхронно обрабатывать построчно.Если я сделаю это синхронно, мне не хватит места в буфере и заблокирую программу.

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