En C #, cuando anula un método, se permite hacer que la anulación sea asíncrona cuando el método original no lo estaba. Esto parece una forma pobre.
El ejemplo que me llevó a esto fue este: me llevaron para ayudar con un problema de prueba de carga. Con alrededor de 500 usuarios concurrentes, el proceso de inicio de sesión se rompería en un bucle de redireccionamiento. IIS estaba registrando excepciones con el mensaje "Un módulo o controlador asíncrono completado mientras una operación asincrónica aún estaba pendiente". Algunas búsquedas me llevaron a pensar que alguien estaba abusando async void
, pero mis búsquedas rápidas a través de la fuente no pudieron encontrar nada.
Lamentablemente, estaba buscando 'async \ svoid' (búsqueda de expresiones regulares) cuando debería haber estado buscando algo más como 'async \ s [^ T]' (suponiendo que la Tarea no estaba completamente calificada ... entiendes el punto).
Lo que más tarde encontré fue async override void onActionExecuting(...
en un controlador base. Claramente ese tenía que ser el problema, y lo era. Arreglar eso (haciéndolo sincrónico por el momento) resolvió el problema.
Volver a la pregunta: ¿Por qué, oh, por qué puede marcar una anulación como asíncrona cuando el código de llamada nunca podría esperarla?
Task
.Respuestas:
La palabra clave asincrónica permite que el método use la
await
sintaxis dentro de su definición. Puedoawait
en cualquier método que devuelva unTask
tipo, independientemente de si es un método asíncrono.void
es un tipo de retorno legal (aunque no recomendado ) para un método asíncrono, entonces, ¿por qué no se permitiría? Desde el exterior,async
no está habilitando nada que no pueda hacer sin él. El método con el que tiene problemas podría haberse escrito para comportarse exactamente igual sin ser asíncrono. Su definición simplemente habría sido más detallada.Para las personas que llaman, un
async T
método es un método normal que los rendimientosT
(que se limita avoid
,Task
oTask<A>
). Que es un método asíncrono no es parte de la interfaz. Tenga en cuenta que el siguiente código es ilegal:(O un código similar en una clase abstracta) produce el siguiente mensaje de error en VS2012:
Si yo hice intención de un método en una clase de interfaz o el padre a ser típicamente asíncrona, no puedo utilizar
async
para comunicar eso. Si quisiera implementarlo con laawait
sintaxis, necesitaría poder tener métodos de anulación asíncrona (en el caso de la clase principal).fuente
override
nada, pero de eso se trata la pregunta.async
no cambia la interfaz de un método, solo lo que está sintácticamente permitido en su definición, por lo que si es una anulación o no es completamente irrelevante.async
modificador solo se puede aplicar a implementaciones. No puede declarar un método asíncrono en una interfaz, por ejemplo, subrayando que si un método es asíncrono o no, no forma parte de la interfaz.El único propósito de la palabra clave asíncrona es hacer esperar dentro del cuerpo de esa función una palabra clave. Esto es necesario para que agregar la funcionalidad de espera no rompa el código existente. Microsoft decidió hacer uso de esperar una opción de suscripción. Para una función que no está marcada como asíncrona, puede definir una variable llamada esperar sin problema.
Por lo tanto, async no es parte de la firma de una función y no tiene un significado semántico en el código IL generado. Está estrictamente allí para que el compilador sepa cómo compilar correctamente la función. También le indica al compilador que se asegure de que solo se devuelva Tarea, Tarea <T> o nulo.
fuente