2012-03-09 14 views
13

Tengo una acción de búsqueda que tiene dos rutas, una ruta síncrona, que solo devuelve una vista simple, y una ruta asíncrona, que realiza la búsqueda de forma asíncrona y luego devuelve una vista. Ambas son solicitudes GET, por lo que son parte de la misma acción.Usar una acción asíncrona para ejecutar el código síncrono

El problema es que cuando accedo a la acción "localhost: XXXX/Home/Search", la página simplemente carga infinitamente. Usando Fiddler, puedo ver que la solicitud nunca vuelve. Lo he depurado y llega a la última línea de código, pero, una vez más, la solicitud no se completa.

He simplificado las repro a lo siguiente:

public async Task<ActionResult> Search() 
{ 
    return View(); 
} 

VS11 me advierte de que el código se ejecutará de forma sincrónica sin esperan, lo cual está bien, pero la solicitud no se completa.

¿Esto debería funcionar? ¿O necesito hacer algo más aquí?

Editar

Esto es MVC 4 focalización .NET 4.5.

Editar 2

Para aquellos que ven las cosas mejor en el código, es por eso que necesito síncrono en una acción asincrónica:

public async Task<ActionResult> Search(string query = null) 
{ 
    if (string.IsNullOrWhiteSpace(query)) 
     return View(new SearchViewModel()); // never loads 

    var model = await _someService.SearchAsync(query); 
    return View(model); // loads 
} 
+0

Creo que esto * debería * funcionar, pero por alguna razón no lo hace. Como arroja y atrapa un 'NullReferenceExcpetion' internamente, creo que es un error. – svick

+1

Consejo: asegúrese de heredar de 'AsyncController', no' Controller' si sus métodos de acción están devolviendo una 'Tarea '. – vcsjones

+0

2 @ vcsjones, lo intenté, pero no ayuda. Y [no debería ser necesario en MVC4] (http://msdn.microsoft.com/en-us/library/system.web.mvc.asynccontroller%28v=vs.108%29.aspx). – svick

Respuesta

16

Este es un problema conocido en la versión beta. To quote Stephen Toub:

La respuesta corta es que hay un error conocido en ASP.NET MVC en .NET 4.5 Beta que da lugar a este problema cuando el método asíncrono se completa de forma sincrónica. Hasta que haya una solución disponible, una solución simple es agregar "aguarde Task.Yield();" como la primera línea del método async, lo que obliga a completar de forma asíncrona. Para que esto funcione correctamente, también hay que asegurarse de que está utilizando el nuevo SynchronizationContext suministrada por ASP.NET en .NET 4.5, lo que significa asegurar que tenga la línea:

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 

en la sección de la configuración appsettings archivo.

Cuestiones relacionadas