variable valor sesión recuperar obtener net asp c# multithreading async-await asp.net-4.5 conceptual

valor - Comprender el contexto en C#5 asincrónico/aguardar



obtener variable de session c# (2)

¿Estoy en lo correcto al afirmar que async / await no tiene nada que ver con concurrencia / paralelismo y que no es más que una implementación de estilo de paso de continuación (CPS)? Y el enhebrado real se lleva a cabo por la instancia SynchronizationContext que await pases / restauraciones?

Si eso es correcto, tengo la siguiente pregunta sobre SynchronizationContext :
garantiza que se ejecutará una continuación en el mismo hilo.

Sin embargo, ¿hay garantías de que la información de contexto del hilo persiste? Me refiero a Name , CurrentPrincipal , CurrentCulture , CurrentUICulture , etc. ¿Depende de framework (ASP.NET, WinForms, WCF, WPF)?


¿Estoy en lo cierto al decir que async / await no tiene nada que ver con la simultaneidad / paralelismo y no es más que la implementación de CPS?

Bueno, async / await es una reescritura que usa CPS, por lo que su comprensión básica es correcta.

En cuanto a "concurrencia" y "paralelismo", diría que sí permite la concurrencia; puede iniciar varias operaciones async que están todas "en vuelo" al mismo tiempo. Esto es fácil de hacer con Task.WhenAll y Task.WhenAny .

Además, aunque async en sí mismo no implica "multihilo", Task.Run habilita fácil async multihilo compatible

Y el enhebrado real se lleva a cabo por la instancia SynchronizationContext que espera pases / restauraciones?

Piénselo de esta manera: la continuación creada por la reescritura de CPS tiene que ejecutarse en alguna parte . El "contexto asíncrono" capturado se puede utilizar para programar la continuación.

Nota al TaskScheduler.Current : el contexto capturado es en realidad SynchronizationContext.Current menos que sea nulo , en cuyo caso el contexto capturado es TaskScheduler.Current .

Otra nota importante: la captura y restauración del contexto depende del objeto "awaiter". Por lo tanto, de forma predeterminada, si await una Task (o cualquier otro incorporado que se pueda esperar), el contexto será capturado y restaurado. Pero si await el resultado de ConfigureAwait(false) , entonces el contexto no se captura. Del mismo modo, si await tu propia costumbre a la espera, no capturará el contexto (a menos que lo programes).

Sin embargo, ¿hay garantías de que la información de contexto del hilo persiste? Me refiero a Nombre, CurrentPrincipal, CurrentCulture, CurrentUICulture, etc.

SynchronizationContext es diferente de ExecutionContext . Una respuesta simplificada es que ExecutionContext siempre "fluye", por lo que CurrentPrincipal fluye (si no lo hizo, podría ser un problema de seguridad, por lo que las API que no fluyen ExecutionContext siempre terminan en Unsafe ).

En las aplicaciones de interfaz de usuario, la cultura no fluye, pero de forma predeterminada es la misma para todos los hilos de todos modos. Name definitivamente no va a fluir, a menos que reanude en el mismo hilo (por ejemplo, usando un UI SynchronizationContext ).

Para leer un poco más, recomiendo comenzar con mi propio tutorial async / await y luego las preguntas frecuentes async / async oficiales . Luego eche un vistazo a la publicación de blog de Stephen Toub en ExecutionContext vs. SynchronizationContext .

También puede encontrar mi artículo SynchronizationContext útil.


No, las palabras clave async / await tienen todo que ver con la concurrencia. async / await básicamente envuelve su código de método en una tarea y continuación. Para ver la traducción exacta que produce el compilador (utilizando la Biblioteca de tareas paralelas) desensamble algunos fragmentos de código. Esta traducción del uso de async / await es ''similar'' (¡pero no idéntica!) Al ejemplo a continuación

async Task<int> TaskOfTResult_MethodAsync() { int hours; // . . . // Return statement specifies an integer result. return hours; } // Calls to TaskOfTResult_MethodAsync Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync(); int intResult = await returnedTaskTResult; // or, in a single statement int intResult = await TaskOfTResult_MethodAsync();

esto es aproximadamente convertido a

private int Result() { int hours; // . . . // Return statement specifies an integer result. return hours; }

donde espera la devolución fuera del método como

int? hours = null; Task<int> task = null; task = Task.Factory.StartNew<int>(() => Result()); task.ContnueWith(cont => { // Some task completion checking... hours = task.Result; }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current);

O bien, puede colocar el código TPL en el método de Result

private int ResultAsync() { int? hours = null; Task<int> task = null; task = Task.Factory.StartNew<int>(() => { int hours; // . . . // Return statement specifies an integer result. return hours; }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current); try { return task.Result; } catch (AggregateException aggEx) { // Some handler method for the agg exception. aggEx.Handle(HandleException); } }

SynchronizationContext no garantiza que la continuación se ejecute en el mismo subproceso para el código async / awate . Sin embargo, puede establecer el contexto utilizando el código TPL, a través de la palabra clave SynchronisationContex .