understanding practices net method best await async asp c# asp.net sql-server async-await

practices - Cualquier desventaja de usar ExecuteReaderAsync de C#AsyncCTP



rest api async c# (2)

Me doy cuenta de que la siguiente pregunta no fue respondida:

Entonces, ¿hay alguna desventaja de usar este nuevo modelo de programación asíncrono aquí?

La desventaja que es muy mínima (cpu menor / afaik de memoria menor), es que debido a la posibilidad de que se ejecute cualquier código después de que una instrucción de espera pueda ejecutarse en un subproceso separado, existe una máquina de estado para almacenar el estado de la ejecución actual Hilo para que la continuación del trabajo pueda ser manejada en otro hilo. Puede leer más sobre la estadística await / async en el blog de Dixin - Comprender C # async / await (1) Compilación .

Hay algunos artículos que indican que las llamadas de base de datos asíncronas son una mala idea en .NET.

En C # Async CTP, hay una extensión System.Data.SqlClient.SqlCommand llamada ExecuteReaderAsync . Tengo algunas operaciones como abajo en mi código existente:

var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString; using (var conn = new SqlConnection(connectionString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount"; cmd.CommandType = System.Data.CommandType.StoredProcedure; conn.Open(); var reader = cmd.ExecuteReader(); while (reader.Read()) { //do the reading } conn.Close(); } }

Hay varias operaciones como esta en mi código. Por lo tanto, estoy pensando en convertirlos en asíncronos.

Pero por otro lado, no veo mucha atracción por este enfoque (quizás no esté mirando en la dirección correcta, ¡quién sabe!).

Entonces, ¿hay alguna desventaja de usar este nuevo modelo de programación asíncrono aquí?

Editar:

Suponiendo que refactorizo ​​el código de la siguiente manera:

public async Task<IEnumerable<Foo>> GetDataAsync() { List<Foo> foos = new List<Foo>(); var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString; using (var conn = new SqlConnection(connectionString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount"; cmd.CommandType = System.Data.CommandType.StoredProcedure; conn.Open(); var reader = await cmd.ExecuteReaderAsync(); while (reader.Read()) { //do the reading //create foos } conn.Close(); } } return foos; }

Por lo que entiendo de la palabra clave await, convierte el código, que está después de él, como continuación. Además, cuando golpea la palabra clave await, regresa inmediatamente a su interlocutor, independientemente del estado de la operación. Cuando termina vuelve y dispara el código de continuación.

Esto es lo que tengo en mente.


No estoy de acuerdo con Ricka en esto. Los comandos de Async DB no solo son buenos, sino que son críticos para lograr escala, rendimiento y latencia. Su objeción sobre el tiempo de incremento del grupo de subprocesos se aplica solo a un servidor web que experimenta bajos volúmenes de tráfico.

En una situación de alto tráfico (que es la única que importa), el grupo de subprocesos no tendrá que esperar a que se "inyecten" nuevos subprocesos. Hacer los comandos SQL de forma asíncrona es importante no solo desde el punto de vista del estado de las solicitudes / subprocesos del servidor web, sino también desde el punto de vista de la vida útil / latencia totales de la solicitud: las llamadas de DB no correlacionadas se pueden hacer en paralelo, en lugar de hacerlo de forma secuencial. Esto solo resulta generalmente en mejoras dramáticas en la latencia de la solicitud HTTP según lo experimentado por el usuario. En otras palabras, tus páginas se cargan más rápido.

Sin embargo, un consejo: el Comando SQL no es verdaderamente asíncrono hasta que habilite Asynchronous Processing=true en la cadena de conexión. Si bien esto no está establecido (y por defecto no lo está, Edit: comenzando con .NET Framework <4.5. Ya no se requiere el Asynchronous Processing ) sus llamadas ''asíncronas'' a BeginExecuteReader no son más que una farsa, la llamada iniciará un hilo y un bloque ese hilo Cuando el procesamiento asíncrono verdadero está habilitado en la cadena de conexión , la llamada es realmente asíncrona y la devolución de llamada se basa en la finalización de IO.

Una advertencia: un comando SQL asíncrono se completa tan pronto como el primer resultado vuelve al cliente y los mensajes de información cuentan como resultado.

create procedure usp_DetailsTagsGetAllFromApprovedPropsWithCount as begin print ''Hello''; select complex query; end

Has perdido todos los beneficios de async. La print crea un resultado que se devuelve al cliente, lo que completa el comando asíncrono y la ejecución en el cliente se reanuda y continúa con el ''reader.Read ()''. Ahora que se bloqueará hasta que la consulta compleja comience a producir resultados. Usted pregunta ''¿quién pone print en el procedimiento?'' pero la print puede estar disfrazada en otra cosa, tal vez algo tan inocente como un INSERT que se ejecuta sin emitir primero un SET NOCOUNT ON .