Aspnetsynchronizationcontext.
-
11-12-2019 - |
Domanda
PRENDERE DI UTILIZZARE IL NUOVO MODELLO ASYNC C # 5 È stato sorprendente per me AspNetSynchronizationContext
è una classe interna (così come la base AspNetSynchronizationContextBase
).Quindi non documentato.Ma è essenziale sapere cosa si tratta quando si utilizza la funzionalità ASYNC / attendi al tuo codice ASP.NET.Sono corretto questo
Garantire le tue continuazioni otterrà lo stesso HttpContext.Current
come chiamanti originali?
non Garanzia Le continuazioni verranno eseguite sullo stesso thread dei chiamanti?
Se quest'ultima ipotesi non è vera e ottengo il filo originale posso essere sicuro di ottenere lo stesso contesto di thread in continuazioni?Voglio dire Principal / Cultura associata al filo e filo stoccaggio locale?Questo è importante perché la localizzazione ASP.NET si basa sulla cultura del thread e la mia applicazione si basa sul modello di sicurezza dei ruoli .NET (Principal del filo).
Soluzione
.Sono corretto che garantisce che le tue continuazioni ottengano lo stesso httpContext.current come chiamanti originali? Non garantisce che le continuazioni vengano eseguite sullo stesso filo dei chiamanti?
Sì,
HttpContext.Current
viene preservato e sì, le continuazioni possono eseguire su un filo diverso..Voglio dire Principal / Cultura associata al thread e al filo Memoria locale? Questo è importante perché la localizzazione ASP.NET si basa sulla cultura del thread e la mia applicazione si basa sul modello di sicurezza dei ruoli .NET (Principal del filo).
L'archiviazione ordinaria del filo-locale è persa. Puoi attenuarlo usando
LogicalCallContext
(che fluisce conExecutionContext
), ma conasync
è più facile fare solo riferimento direttamente le variabili.Principal è sempre preservato; fare diversamente sarebbe un rischio per la sicurezza. Questo foglie con
ExecutionContext
.Credo che la cultura scorre con
AspNetSynchronizationContext
, ma non ho testato questo su .NET 4.5 La nuova implementazione .
.Puoi trovare il mio MSDN Articolo su
SynchronizationContext
utile. Non è una documentazione ufficiale (non lavoro per Microsoft), ma almeno è qualcosa. Si noti che ilAspNetSynchronizationContext
referenziato in quell'articolo è ora chiamatoLegacyAspNetSynchronizationContext
in .NET 4.5.Un'altra grande risorsa è Stephen Toubs
ExecutionContext
vs.SynchronizationContext
.
Altri suggerimenti
Bene, pur catturando l'esecuzioneContext è sempre garantito, catturare e eseguire l'esecuzione sullo stesso sincronizzazioneContext dipende dal attesatore.
L'attesa più comune (il tipo restituito dal metodo di getwawaiter () che è chiamato internamente quando "attendi" qualcosa) è il taskawaiter che è tornato da task.getawaiter (). Per impostazione predefinita, il taskawaiter catturerà il sincronizzazione correnteContext e esegui il delegato di continuazione sul sincronizzazione catturatoContext . Il che significa, sarai in grado di utilizzare httpContext.Current nel resto del tuo metodo, e non ti dispiace che funzionerà come continuazione. Quindi, questo codice funzionerà come previsto (la parte in cui scrive "B" si eseguirà sullo stesso sincronizzazioneContext della prima riga):
.
HttpContext.Current.Response.Write("A");
await Task.Delay(1000);
HttpContext.Current.Response.Write("B")
È possibile modificare questo comportamento utilizzando il metodo Task.ConfigureAwait(false)
, che indica al mai vero il resto del resto del metodo al sincronizzazione originale.
Certo, se si utilizza Task.Run o Task.Factory.StartNow nel metodo ASYNC che stai chiamando, è responsabilità di catturare nuovamente il sincronizzazioneContext.
buona fortuna.