understanding net mvc example await async asp c# asp.net asp.net-web-api async-await

c# - net - ¿Por qué es HttpContext.Current null después de esperar?



web api async controller (3)

¿Está mi prueba defectuosa, o hay algún elemento web.config que me falta aquí que haría que HttpContext.Current resuelva correctamente después de aguardar?

Su prueba no es defectuosa y HttpContext.Current no debe ser nulo después de la espera porque en ASP.NET Web API cuando lo espere, se asegurará de que el código que sigue a esta espera se transmita al HttpContext correcto que estaba presente antes de aguardar.

Tengo el siguiente código de prueba de WebAPI, no uso WebAPI en producción, pero lo hice debido a una discusión que tuve sobre esta pregunta: pregunta asincrónica de WebAPI

De todos modos, aquí está el método WebAPI ofensivo:

public async Task<string> Get(int id) { var x = HttpContext.Current; if (x == null) { // not thrown throw new ArgumentException("HttpContext.Current is null"); } await Task.Run(() => { Task.Delay(500); id = 3; }); x = HttpContext.Current; if (x == null) { // thrown throw new ArgumentException("HttpContext.Current is null"); } return "value"; }

Creí que se esperaba la segunda excepción porque, cuando se await , es probable que esté en un hilo diferente donde HttpContext.Current como una variable estática de subprocesos ya no se resolverá con el valor apropiado. Ahora, en función del contexto de sincronización, en realidad podría verse obligado a volver al mismo hilo después de la espera, pero no estoy haciendo nada sofisticado en mi prueba. Esto es solo un uso simple e ingenuo de await .

En comentarios en otra pregunta, me dijeron que HttpContext.Current debería resolverse después de una espera. Incluso hay otro comentario sobre esta pregunta que indica lo mismo. Entonces, ¿qué es verdad? ¿Debería resolverse? Creo que no, pero quiero una respuesta autorizada sobre esto porque async y await es lo suficientemente nuevo como para no encontrar nada definitivo.

TL; DR: ¿Es HttpContext.Current potencialmente null después de una await ?


Asegúrese de escribir una aplicación ASP.NET 4.5 y una orientación 4.5. async y await tienen un comportamiento indefinido en ASP.NET a menos que esté ejecutando 4.5 y esté usando el nuevo contexto de sincronización "amigable para la tarea".

En particular, esto significa que usted debe:

  • Establezca httpRuntime.targetFramework en 4.5 , o
  • En su appSettings , configure aspnet:UseTaskFriendlySynchronizationContext en true .

Más información está disponible aquí .


Como @StephenCleary señaló correctamente, necesita esto en su web.config:

<httpRuntime targetFramework="4.5" />

Cuando estaba solucionando este problema por primera vez, hice una búsqueda en toda la solución de lo anterior, confirmé que estaba presente en todos mis proyectos web y rápidamente lo descarté como el culpable. Finalmente, se me ocurrió mirar esos resultados de búsqueda en contexto completo:

<!-- For a description of web.config changes for .NET 4.5 see http://go.microsoft.com/fwlink/?LinkId=235367. The following attributes can be set on the <httpRuntime> tag. <system.Web> <httpRuntime targetFramework="4.5" /> </system.Web> -->

Doh.

Lección: si actualiza un proyecto web a 4.5, aún necesita obtener esa configuración en su lugar de forma manual.