2009-11-14 13 views
6

¿Cuál es la ventaja de utilizar el procesamiento asíncrono en SQL Server sobre el procesamiento asincrónico .NET? ¿No son lo mismo? Tengo dificultades para entender cuál es la ventaja de utilizar el procesamiento asincrónico en SQL Server en lugar de .NET APM. Puedo envolver fácilmente una llamada SQL en una expresión lambda y hacer un BeginInvoke (...).Procesamiento asincrónico en SQL Server frente a .NET Procesamiento asíncrono

¿Alguien puede ayudarme con la diferencia y el beneficio de ambos?

Respuesta

9

El problema con el procesamiento asíncrono .NET (BeginInvoke(...)) es que todo esto es hacer está girando un hilo para procesar el código de forma sincrónica. Una consulta de 5 minutos atará un hilo durante 5 minutos, bloqueando (es decir, no haciendo nada durante ~ 99% del tiempo) mientras que el resultado se calcula en el extremo remoto. Bajo tensión (muchas consultas a la vez) esto agotará el grupo de hilos, atando todos los hilos en un estado bloqueado. The threadpool dejará de responder y las nuevas solicitudes de trabajo sufrirán una gran latencia a la espera de que el threadpool active hilos adicionales. Este no es el uso previsto del grupo de subprocesos, ya que está diseñado con la expectativa de que las tareas que se le pidan completar sean efímeras y no bloqueantes.

Con los pares APM Begin/EndAction, uno puede invocar la misma acción de forma no bloqueante, y solo cuando el resultado se devuelve mediante un puerto de terminación IO se pone en cola como un elemento de trabajo en el threadpool. Ninguno de sus subprocesos está vinculado temporalmente, y en el punto en que se trata la respuesta en cola, los datos están disponibles, lo que significa que el código de usuario no se bloquea en IO, y puede completarse rápidamente ... un uso mucho más eficiente del threadpool que se adapta a muchas más solicitudes de clientes sin el costo de un hilo por operación pendiente.

0

De este artículo SQL Server 2008 Books Online (October 2009) - Performing Asynchronous Operations, cito:

procesamiento asincrónico permite métodos para volver inmediatamente sin bloqueo en el subproceso de llamada. Este permite gran parte de la potencia y flexibilidad del multihilo, sin que requiera que el desarrollador explícitamente cree subprocesos o maneje la sincronización .

Si ha creado explícitamente esos hilos y ha manejado la sincronización, tal vez probablemente no encontrará mucha diferencia.

+0

Creo que quiere decir "¿Por qué usar un proveedor de datos? BeginExecute ___()/EndExecute ____() 'frente a solo envolverlos en un delegado. –

+0

@Joel: Hmm ... tal vez tengas razón. –

0

Si se refiere a "¿Por qué utilizar un proveedor de datos BeginExecute___()/EndExecute____() métodos vs simplemente envolviendo una Execute____() normales en un delegado, sospecho que la respuesta es que cuando estaban diseñando en primer lugar el modelo de proveedor de ado.net para .Net 1.0, envolviendo algo en un delegado e invocarlo de forma asíncrona no era tan simple.

Otros posibles motivos son que esto coincidía con el código antiguo que se actualizaron o que se ajustaban para el .Net original funcionó o que los métodos integrados le permiten fácilmente verifique las excepciones devueltas

+0

Quizás los tipos de MS de su. El equipo de NET sabe mejor: P –

+1

SqlClient's BeginExecute/EndExecute usa async IO si la conexión está configurada correctamente, no es solo una invocación asincrónica de delegado común. –

3

.Net BeginInvoke simplemente pospone la ejecución en un hilo diferente. Esto siempre será más lento que una llamada síncrona y consumirá recursos adicionales. La única razón por la que esto se utilizaría sería liberar el contexto de la persona que llama para continuar con otras operaciones (por ejemplo, devolver el resultado de una solicitud HTTP al cliente).

Los métodos asíncronos SqlClient, cuando la propiedad AsynchronousProcessing en la conexión se establece en true y se usan los métodos BeginExecute de SqlCommand, son realmente asíncronos.El comando SQL se publica en el canal de comunicación de la red y la finalización se invoca cuando el servidor devuelve el resultado.

Desde un punto de vista de la fiabilidad aunque ninguno de estos métodos es útil sin embargo. Ambos dependen del proceso del cliente para quedarse hasta que se complete la llamada; de lo contrario, el servidor SQL vería al cliente desconectarse y abandonar el procesamiento, haciendo retroceder cualquier trabajo intermedio. Considere una aplicación ASP que aceptó una solicitud HTTP, envió un proceso de pago 'asíncrono' y devolvió una respuesta. No hay ninguna forma de garantizar que el trabajo enviado se realice realmente.

Para situaciones en las que el tratamiento requiere fiabilidad garantiza la solución es el trabajo hacen cola en el servidor, lo cometen y luego proceder, confiando en las propias capacidades de procesamiento asíncrono de SQL Server. Este es un método que garantiza el procesamiento incluso en presencia de desconexiones de clientes, proceso de ASP 'reciclaje', duplicación de SQL Server o failovers de clúster, recuperación ante desastres de hardware, casi cualquier cosa que pueda arrojar, ya que es una forma transaccionalmente duradera de enviar solicitudes de procesamiento asincrónico. Para un ejemplo vea Asynchronous Procedure Execution.

5

Como se mencionó en las respuestas anteriores, BeginInvoke utiliza un hilo de .NET. Sin embargo, igualmente importante es que el hilo proviene del grupo de subprocesos de ASP.NET, por lo que compite con los clientes por recursos de subprocesos muy limitados. Lo mismo es cierto para ThreadPool.QueueUserWorkItem().

Las llamadas asincrónicas SqlClient requieren un SqlConnection que tenga async = true habilitado. Ese modo requiere un poco más de sobrecarga de red (razón por la cual no está habilitado por defecto), pero no consume un hilo del grupo de subprocesos de .NET. En cambio, usa asincronización de E/S.

La ventaja de este último enfoque es que es mucho más escalable. Puede procesar cientos o miles de solicitudes simultáneas de esa manera, donde la sobrecarga con un hilo por llamada sería extrema. Además, consumiría todo el grupo de subprocesos ASP.NET muy rápidamente (solo tiene un máximo de alrededor de 12 subprocesos por defecto).

Cuestiones relacionadas