Почему я должен использовать асинхронную операцию вместо синхронной?

Я всегда думал об этом.

Допустим, у нас есть простой асинхронный веб-запрос с использованием класса 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 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам