Почему асинхронный режим лучше, чем синхронный, при обработке запросов клиентов? - PullRequest
4 голосов
/ 02 июля 2010

У меня есть клиент-серверный проект, и я искал лучший способ обработки запросов от клиентов. Некоторые считают, что асинхронный режим лучше, чем синхронный режим и режим пула потоков.
Мой вопрос почему? И есть ли недостатки в асинхронном режиме?

Ответы [ 6 ]

7 голосов
/ 02 июля 2010

Да, асинхронные запросы часто могут обрабатываться без затрат потока. Операционная система имеет специальную поддержку для них, такие как перекрывающиеся порты ввода-вывода и завершения. По сути, они используют затраты на поток ядра, который в любом случае необходим, потому что драйвер должен иметь возможность обрабатывать несколько запросов от нескольких программ пользовательского режима. .NET Framework легко использует это в своих методах BeginXxx ().

Использование потоков пула потоков также дешево, но вы подчиняетесь поведению планировщика пула потоков. Который не очень любит запускать больше потоков TP, тогда как есть ядра. Потоки TP никогда не должны использоваться для кода, который может какое-то время оставаться заблокированным, что довольно типично для задач CS, таких как установление соединения.

Обработка ошибок в асинхронном коде очень сложна. Обычно у вас очень мало контекста, когда метод EndXxxx () вызывает исключение. Это происходит в потоке обратного вызова, очень далеко от основной логики. Хорошо, когда вы можете пожать плечами «не случилось, давайте запишем это», полный бедлам и перезвон, когда от этого зависит состояние программы. Всегда выбирайте синхронный режим в последнем случае.

2 голосов
/ 02 июля 2010

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

2 голосов
/ 02 июля 2010

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

1 голос
/ 02 июля 2010

Чтобы «пометить» ответ Ханса: независимость операций ввода-вывода от потоков позволяет значительно более значительное масштабирование;возможны десятки тысяч невыполненных запросов, которые просто не могут быть выполнены с использованием потоков.

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

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

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

1 голос
/ 02 июля 2010

Одним из недостатков синхронных операций является IMO, что вы не можете их прервать - например, когда ваше серверное приложение вызывает синхронный метод WaitForConnection () и клиент не подключается, вы не можете перестать ждать ...

ДляНапример, попробуйте взглянуть на это Что такое хороший способ завершить работу Темы, заблокированные на NamedPipeServer # WaitForConnection?

0 голосов
/ 02 июля 2010

На синхронном сервере вы должны обрабатывать блокировки при доступе к вашим структурам данных (если имеются обновления), и это требует времени и кода (и является источником трудных для поиска ошибок). Кроме того, наличие множества (например, тысяч) потоков создает технические проблемы во многих реализациях (например, для выделения стека), и если сервер связан с вводом-выводом, эти потоки почти все спят (ожидают сеть) и просто тратят память.

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

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

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

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