without understanding run method example ejemplos create await async c# multithreading asynchronous synchronizationcontext

understanding - ¿Qué significa exactamente ''contexto'' en el código C#async/await?



task run async c# (2)

Como describo en mi entrada de blog de introducción async , el "contexto" es:

  • SynchronizationContext.Current , a menos que sea null , en cuyo caso es
  • TaskScheduler.Current . Tenga en cuenta que si no hay un programador de tareas actual, TaskScheduler.Current es el mismo que TaskScheduler.Default , que es un contexto de grupo de subprocesos.

La gran mayoría de las veces, esto es un contexto de solicitud UI o ASP.NET (ambos tipos de SynchronizationContext ), o bien es el contexto del grupo de subprocesos. Los contextos del programador de tareas rara vez entran en juego.

Tenga en cuenta que este contexto solo se utiliza para programar la continuación . No hace nada con el cálculo de referencias; en su ejemplo, obj se captura tal como sería si se hiciera referencia a una expresión lambda.

Veamos algunos códigos simples de C # async / await donde tengo una referencia de objeto ( obj ) antes y después de una await con ConfigureAwait(false)

private async Task<SomeObject> AnAsyncLibraryMethod(SomeObject obj) { Console.WriteLine(Thread.CurrentThread.ManagedThreadId); obj.Name = "Harry"; // <-- obj here // MAIN POINT var newSubObj = await FetchOverHttpAsync().ConfigureAwait(false); // Continuation here Console.WriteLine(Thread.CurrentThread.ManagedThreadId); obj.Name = "Sally"; // <-- same obj here return obj; } public class SomeObject { public string Name; }

ConfigureAwait(false) parece no indicar la continuación del contexto original capturado , pero ¿qué significa eso realmente? He intentado el código anterior y obj se referencia correctamente en la parte posterior (incluso cuando se reanuda en un subproceso diferente).

Por lo tanto, el "contexto" no parece ser la memoria de trabajo del hilo (es decir, el almacenamiento local del hilo). Entonces, ¿qué contiene "contexto"? Por lo tanto, ¿qué significa realmente para

marque la continuación de vuelta al contexto original capturado


Si no estoy totalmente equivocado, ConfigureAwait(false); solo significa que el código que se ejecuta después del código que está esperando, no está obligado a usar SynchronizationContext desde antes de la espera.

SynchronizationContext puede ser diferente según lo señalado por Stephen. Entonces, imagine que está en un entorno web y su código después de la espera depende de HttpContext.Current.Items, esto podría no funcionar más si configura ConfigureAwait(false);

El siguiente código en un controlador MVC lanzaría una excepción por ejemplo

public async Task<ActionResult> Index() { System.Web.HttpContext.Current.Items["test"] = "test"; var result = await SomethingAsync(); return View(); } private async Task<object> SomethingAsync() { await Task.Delay(1000).ConfigureAwait(false); // this will throw a nullpointer if ConfigureAwait is set to false return System.Web.HttpContext.Current.Items["test"]; }

Sin embargo, su variable está simplemente en el alcance del método y, por lo tanto, estará disponible, básicamente el método de cierre / alcance, si esto tiene sentido.