Асинхронная обработка в SQL Server против .NET Асинхронная обработка - PullRequest
6 голосов
/ 14 ноября 2009

В чем преимущество использования асинхронной обработки в SQL Server по сравнению с .NET асинхронной обработкой? Разве они не одинаковы? Мне трудно понять, в чем преимущество использования асинхронной обработки в SQL Server вместо .NET APM. Я могу легко обернуть вызов SQL в лямбда-выражение и выполнить BeginInvoke (...).

Может ли кто-нибудь помочь мне в разнице и пользе от обоих?

Ответы [ 5 ]

9 голосов
/ 14 ноября 2009

Проблема с асинхронной обработкой .NET (BeginInvoke(...)) состоит в том, что все, что она делает, - это выделение потока для синхронной обработки кода. 5-минутный запрос будет связывать поток в течение 5 минут, блокируя (т.е. ничего не делая в течение ~ 99% времени), пока результат вычисляется на удаленном конце. Под нагрузкой (много запросов одновременно) это исчерпает пул потоков, связывая все потоки в заблокированном состоянии. Пул потоков перестанет отвечать, а новые рабочие запросы будут испытывать большие задержки, ожидая, пока пул потоков запустит дополнительные потоки. Это не предполагаемое использование пула потоков, так как он разработан с расчетом на то, что задачи, которые ему предлагается выполнить, должны быть кратковременными и неблокирующими.

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

5 голосов
/ 16 ноября 2009

Как упоминалось в предыдущих ответах, BeginInvoke использует поток .NET. Не менее важно то, что этот поток происходит из пула потоков ASP.NET, поэтому он конкурирует с клиентами за очень ограниченные ресурсы потоков. То же самое верно для ThreadPool.QueueUserWorkItem().

Для асинхронных вызовов SqlClient требуется SqlConnection с включенным async = true. Этот режим требует немного больше нагрузки на сеть (поэтому он не включен по умолчанию), но он не потребляет поток из пула потоков .NET. Вместо этого он использует асинхронный ввод / вывод.

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

3 голосов
/ 14 ноября 2009

.Net BeginInvoke просто откладывает выполнение в другой поток. Это всегда будет медленнее, чем синхронный вызов, и потребляет дополнительные ресурсы. Единственная причина, по которой это можно было бы использовать, состоит в том, чтобы освободить контекст вызывающей стороны для перехода к другим операциям (например, вернуть клиенту результат HTTP-запроса).

Асинхронные методы SqlClient, когда свойство AsynchronousProcessing для соединения установлено в значение true и используются методы BeginExecute SqlCommand, являются действительно асинхронными. Команда SQL отправляется в сетевой канал связи, и завершение вызывается, когда результат возвращается сервером.

С точки зрения надежности, хотя ни один из этих методов не является полезным. Они оба полагаются на то, что клиентский процесс остается в стороне до завершения вызова, иначе SQL Server увидит, что клиент отключится и откажется от обработки, откатив любую промежуточную работу. Рассмотрим приложение ASP, которое приняло HTTP-запрос, отправило «асинхронную» обработку платежей и вернуло ответ. Нет никакого способа гарантировать, что представленная работа действительно произойдет.

В ситуациях, когда обработка требует надежности, гарантируется, что решение поставит в очередь работу на сервере, зафиксирует ее и затем продолжит работу, полагаясь на собственные возможности асинхронной обработки SQL Server. Это метод, который гарантирует обработку даже при наличии клиентских отключений, «перезапуске» процесса ASP, отказоустойчивости зеркалирования или кластеризации SQL Server, аппаратного аварийного восстановления, практически всего, что вы можете использовать, поскольку это надежный способ отправки транзакций. асинхронная обработка запросов. Пример см. Асинхронное выполнение процедур .

0 голосов
/ 14 ноября 2009

Если вы имеете в виду «Зачем использовать методы поставщиков данных BeginExecute___()/EndExecute____(), а не просто перенос нормального Execute____() в делегате, я подозреваю, что ответ заключается в том, что когда они впервые разрабатывали модель поставщика для ado.net для .Net 1.0 завернуть что-либо в делегат и вызвать его асинхронно не так просто.

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

0 голосов
/ 14 ноября 2009

Из этой статьи Электронная документация по SQL Server 2008 (октябрь 2009 г.) - Выполнение асинхронных операций , цитирую:

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

Если вы явно создали эти потоки и обработали синхронизацию, возможно, вы не найдете большой разницы.

...