2012-08-09 19 views
11

Tengo que llamar a un método que devuelve un Task desde dentroLa prevención de un punto muerto cuando se llama a un método asíncrono sin utilizar esperan ser

public override void OnActionExecuting(ActionExecutingContext filterContext) 

no va dejar que me hacen que este método asíncrono que arroja el siguiente

Un módulo o controlador asíncrono completado mientras que una operación asíncrona todavía estaba pendiente.

y al llamar

entityStorage.GetCurrentUser().Result 

llego a un punto muerto. ¿Cómo puedo evitar esto?

que han estado jugando un rato con él viene con cosas como

entityStorage.GetCurrentUser().Result.ConfigureAwait(false).GetAwaiter().GetResult(); 

Pero esto no está funcionando. ¿Cómo puedo hacerlo? Mi solución deberá funcionar con ASP.NET 4 y el Async Targetting Pack, no puedo usar ASP.NET 4.5 mientras estoy implementando en Azure.

+0

Encontraron una respuesta aquí http://stackoverflow.com/a/5097066/168012 si alguien tiene una mejor solución, por favor comparta – Tom

+2

¿Se deriva de 'AsyncController' en lugar de' Controller'? –

+0

Por favor, [vote aquí] (https://aspnet.codeplex.com/workitem/9582) para que el equipo de MVC agregue compatibilidad con los filtros de acción 'async'. –

Respuesta

2

Dado que aguardar solo es un azote de sintaxis para que el compilador reescriba una continuación para usted, la ruta más 'directa' sería tomar el código que le esperara y convertirlo en una llamada ContinueWith.

Por lo tanto, algo así como:

entityStorage.GetCurrentUser().ContinueWith(t => 
{ 
    // do your other stuff here 
}); 
12

La causa del interbloqueo es explained here. En resumen, no bloquee en el código async. Debe usar ConfigureAwait(false) en su biblioteca async código y await los resultados (no usar Result o Wait).

Actualización: Por favorvote here para el equipo MVC para añadir soporte para async filtros de acción.

+0

Me está costando encontrar el enlace/página que lo dice, pero he tenido otros que me dicen en el pasado que si proporciona un enlace (especialmente uno externo a SO) debe copiar los bits clave en el SO responder. Sin embargo, de alguna manera se menciona aquí, FWIW: http://meta.stackexchange.com/questions/118582/what-is-an-acceptable-answer –

+0

Tiene razón; La meta pregunta a la que se refiere ha sido eliminada recientemente como parte de la estrategia "hagamos que SO sea un lugar más agradable". Sin embargo, como comentó Jon Skeet: si conozco la respuesta y solo tengo tiempo para publicar un enlace, es mejor que nada. –

+0

El problema que tuve es que si traté de usar la palabra clave async y hacer el método asincrónico, entonces el método arrojó 'Un módulo asincrónico o controlador completado mientras que una operación asincrónica todavía estaba pendiente'. – Tom

1

Si MUST convertido asynch para sincronizar.

public User GetCurrentUserSynch() 
    { 
     return Task.Run(() => 
     { 
      var asyncResult = entityStorage.GetCurrentUser(); 
      while (!asyncResult.IsCompleted) 
      { 
       Application.Current.TryFindResource(new object()); // This is for WPF but you can do some other nonsense action of your choosing 
      } 

      return asyncResult.Result; 
     }).Result; 
    } 

De lo contrario, utilice @ Stephen's answer.

Cuestiones relacionadas