asp.net - AspNetSynchronizationContext
asynchronous async-await (2)
¿Estoy en lo cierto al afirmar que garantiza que sus continuaciones obtendrán el mismo HttpContext.Current como llamadores originales? ¿No garantiza que las continuaciones se ejecutarán en el mismo hilo que las personas que llaman?
Sí, se conserva HttpContext.Current
, y sí, las continuaciones pueden ejecutarse en un hilo diferente.
¿Me refiero a principal / cultura asociado con el hilo y el almacenamiento local de hilo? Eso es importante porque la localización de ASP.NET se basa en la cultura del hilo y mi aplicación se basa en el modelo de seguridad de rol .NET (principal del hilo).
Se ha perdido el almacenamiento local de subprocesos. Puede mitigar esto utilizando LogicalCallContext
(que fluye con ExecutionContext
), pero con async
es más fácil simplemente hacer referencia a las variables directamente.
El principal siempre se conserva; Hacer lo contrario sería un riesgo de seguridad. Esto fluye con ExecutionContext
.
Creo que la cultura fluye con AspNetSynchronizationContext
, pero no he probado esto en la nueva implementación de .NET 4.5 .
Puede encontrar útil mi artículo de MSDN sobre SynchronizationContext
. No es documentación oficial (no trabajo para Microsoft), pero al menos es algo. Tenga en cuenta que el AspNetSynchronizationContext
al que se AspNetSynchronizationContext
referencia en ese artículo ahora se llama LegacyAspNetSynchronizationContext
en .NET 4.5.
Otro gran recurso es ExecutionContext
vs. SynchronizationContext
Stephen Toub.
Al intentar usar el nuevo modelo asíncrono C # 5, me sorprendió AspNetSynchronizationContext
es una clase interna (así como la base AspNetSynchronizationContextBase
). Así indocumentados. Pero es esencial saber qué hace cuando utiliza la función async / await dentro de su código ASP.NET. ¿Estoy en lo cierto al afirmar que garantiza que sus continuaciones obtendrán el mismo HttpContext.Current
como llamadores originales? ¿No garantiza que las continuaciones se ejecutarán en el mismo hilo que las personas que llaman?
Si este último supuesto no es verdadero y obtengo el hilo original, ¿puedo asegurarme de obtener el mismo contexto de hilo en las continuaciones? ¿Me refiero a principal / cultura asociado con el hilo y el almacenamiento local de hilo? Eso es importante porque la localización de ASP.NET se basa en la cultura del hilo y mi aplicación se basa en el modelo de seguridad de rol .NET (principal del hilo).
Bueno, mientras que la captura del ExecutionContext siempre está garantizada, la captura y ejecución de la ejecución en el mismo SynchronizationContext depende del Awaiter.
El aguardador más común (el tipo devuelto por el método GetAwaiter () que se llama internamente cuando "espera" algo) es TaskAwaiter que devolvió Task.GetAwaiter (). Por defecto, TaskAwaiter capturará el actual SynchronizationContext y ejecutará el delegado de continuación en el SynchronizationContext capturado . Lo que significa que podrás usar HttpContext.Current en el resto de tu método, y no te importa que se ejecute como una continuación. Entonces, este código funcionará como se esperaba (la parte en la que escribe "B" se ejecutará en el mismo contexto de sincronización que la primera línea):
HttpContext.Current.Response.Write("A");
await Task.Delay(1000);
HttpContext.Current.Response.Write("B")
Puede cambiar este comportamiento utilizando el Task.ConfigureAwait(false)
, que le dice al que lo espera que no marque el resto del método en el SynchronizationContext original.
Por supuesto, si usa Task.Run o Task.Factory.StartNew en el método asíncrono al que está llamando, es su responsabilidad capturar nuevamente SynchronizationContext.
La mejor de las suertes.