2012-04-04 19 views
15

Estaba trabajando en una presentación y pensé que lo siguiente debería fallar dado que ActionResult no se está devolviendo en el contexto correcto. He cargado la prueba con VS y no obtuve errores. Lo he depurado y sé que está cambiando de tema. Entonces parece que es un código legítimo.Llamar a ConfigureAwait desde una acción MVC de ASP.NET

¿A ASP.NET no le importa en qué contexto o subproceso está como una aplicación de cliente? Si es así, ¿qué propósito proporciona el AspNetSynchronizationContext? No me siento bien poniendo un ConfigureAwait en la acción en sí. Algo parece estar mal al respecto. ¿Alguien puede explicar?

public async Task<ActionResult> AsyncWithBackendTest() 
    { 
     var result = await BackendCall().ConfigureAwait(false); 
     var server = HttpContext.Server; 
     HttpContext.Cache["hello"] = "world"; 
     return Content(result); 
    } 
+2

Una respuesta correcta debería decir por qué hacer esto está totalmente bien o debería dar un ejemplo de lo que falla cuando intenta esto.Mi instinto me dice que no debería, pero me gustaría tener hechos que me respalden. –

Respuesta

6

ASP.NET no tiene el 'hilo de interfaz de usuario' necesidad de que muchos clientes hacen aplicaciones (debido al marco de interfaz de usuario debajo de ella). Ese contexto no se trata de afinidad hilo, pero para el seguimiento de los avances página (y otras cosas, como llevar todo el contexto de seguridad para la solicitud)

Stephen Toub mentions this in an MSDN article:

Windows Forms no es el único entorno que proporciona una clase SynchronizationContext-derived. ASP.NET también proporciona uno, AspNetSynchronizationContext, aunque no es público y no significa para el consumo externo. Más bien, se utiliza bajo las sábanas por ASP.NET para facilitar la funcionalidad de páginas asíncronos en ASP.NET 2,0 (para más información, véase msdn.microsoft.com/msdnmag/issues/05/10/WickedCode). Esta aplicación permite ASP.NET para impedir que se complete el procesamiento de la página hasta que todas las invocaciones asíncronas pendientes se han completado.

Un poco más detalle sobre el contexto de sincronización se da en Stephen Cleary's article from last year.

la figura 4 en particular, muestra que no tiene el comportamiento 'hilo específico' de WinForms/WPF, pero todo esto es una gran lectura.

Si varias operaciones a la vez completa para la misma aplicación, AspNetSynchronizationContext asegurará que se ejecutan uno a la vez . Pueden ejecutar en cualquier hilo, pero ese hilo tendrá la identidad y cultura de la página original.

+0

En la sincronización asíncrona basada en eventos, se aplican invocaciones asincrónicas sobresalientes, pero no parece aplicarse en asincrónica basada en tareas, ya que no habría invocaciones pendientes al final de la acción. Además, a través de la depuración, veo que la identidad del formulario del usuario y sus idiomas (seguridad y cultura) siguen intactos después de ConfigureAwait. Así que estoy leyendo las razones de SyncContext, pero nada parece estar roto. ¿Qué puedo hacer para probar que ConfigureAwait no debe usarse aquí? –

4

En su código, HttpContext es miembro de su clase base AsyncController. No es el contexto actual para el hilo de ejecución.

También, en su caso, HttpContext sigue siendo válida, ya que la solicitud no ha terminado todavía.

No puedo probar esto en este momento, pero esperaría que falle si usaste System.Web.HttpContext.Current en lugar de HttpContext.

P.S. La seguridad es siempre propagada, independientemente de ConfigureAwait - esto tiene sentido si lo piensas. No estoy seguro acerca de la cultura, pero no me sorprendería si siempre se propagara también.

+0

Sí, mis variables siempre serán válidas porque simplemente se envuelven en la pila. Pero incluso System.Web.HttpContext.Current todavía tiene datos válidos y correctos. –

+0

¿'BackendCall' vuelve síncrono? –

+0

No. Además de una verificación lógica, lo he depurado y lo he visto cambiar de tema. –

Cuestiones relacionadas