2012-09-18 28 views
30

Tengo un filtro de acción que cuando se usa en ciertas condiciones específicas tiene que realizar una llamada al servicio web para garantizar que el estado actual sea válido. Inicialmente, esto parecía un candidato ideal para asíncrono/esperan, pero me he encontrado con un obstáculo:Filtro de acción asíncrono en MVC 4

asumir una solicitud a:/Prueba/FilteredAction comienza

  • MyCustomActionFilter ejecutar
    • El primer "esperan" declaración se alcanza
  • TestController.FilteredAction comienza a ejecutar
  • MyCustomActionFilter reanuda la ejecución

Tradicionalmente, esperaría que el filtro de acción reanude la ejecución y luego se complete antes de que la acción del controlador comience a ejecutarse, pero esto no sucede.

Ahora supongo que esto se debe a que estoy usando:

public class MyCustomActionFilter : ActionFilterAttribute 
{ 
    public override **async** void OnActionExecuting(FilterContext context) 
    { 
     var foo = await WebServiceCall(); 
    } 
} 

Así que creo que mi pregunta es: ¿Hay una clase de filtro de acción asíncrono conscientes integrado en MVC 4, o debo bloquear las llamadas aquí?

+0

Ha intentado aplicar el método descrito en [el blog de a'vron] (http://ayende.com/blog/163170/building-async-unit-of-work-with-mvc-4)? – ITmeze

+0

Recientemente he publicado [una biblioteca] (https://www.nuget.org/packages/Hydrogen.Extensions.Mvc5.Async) que agrega la compatibilidad adecuada para filtros asíncronos (basado en gran medida en el código de [ASP.NET MVC] Núcleo] (https://github.com/aspnet/Mvc)). La fuente también está disponible aquí: https://github.com/jdaigle/Hydrogen.Extensions.Mvc5. –

Respuesta

37

MVC no tiene un filtro de acción compatible async (pero WebAPI does have one).

Por ahora, le recomendamos que use llamadas de bloqueo en OnActionExecuting. Con suerte, MVC tendrá una mejor historia en el futuro.

Actualización: Puede vote here para que el equipo de MVC agregue filtros async.

+0

¡Ojalá pudieran soportar razor ootb con API web y entonces podríamos eliminar asp.net mvc por completo! – superlogical

+0

@StephenCleary: creo que un filtro no asíncrono funciona bien en una acción asíncrona. ¿Me puede mostrar un escenario que necesita un filtro de acción compatible con asincronización? Gracias. –

+2

+1 @DannyChen, el filtro que llama a un servicio para verificar algo es un ejemplo exacto de por qué quiere soporte asincrónico para filtros. El problema no es que el filtro síncrono no funcione, sino que el filtro asíncrono funcionaría mucho mejor. –

1

No, no hay filtro asíncrono para MVC, pero es factible.

Los filtros ASP.NET MVC se basan en el concepto de ordenarse, un filtro está garantizado (si se especifica. Consulte el Order property en el IMvcFilter interface) para ejecutar en un orden determinado, si se especifica.

Los temas que tienen que abordarse a la luz de esto son:

  • Para los filtros existentes que no son asíncrono (al menos no implementado de esa manera porque no hay otra manera), es lo que obtener su propia tarea o continuar con la anterior? Es una pregunta importante para responder, ya que hay que sopesar el beneficio de no continuar el siguiente filtro en otro subproceso y mantenerlo mientras otras solicitudes podrían usarlo.

  • Para los filtros que tienen el mismo orden especificado, ¿se ejecutan en paralelo o uno después de otro? Hacer el método asincrónico abre aún más esta posibilidad (aunque podría haberse hecho antes con una firma que no es asincrónica) y es definitivamente un cambio arquitectónico que podría tener un impacto en el rendimiento y el resultado esperado. La respuesta aquí no es tan simple y tendría que basarse en pruebas y compatibilidad con versiones anteriores.

+4

No creo que sea tan complicado. Los filtros pueden provocar un cortocircuito en los resultados, por lo que no tiene más remedio que ejecutarlos secuencialmente, ya sean sincronizados o no sincronizados. Este es el comportamiento existente y, por lo tanto, no pueden surgir problemas de compatibilidad con versiones anteriores. –

Cuestiones relacionadas