Ich habe den folgenden Test-WebAPI-Code. Ich verwende WebAPI nicht in der Produktion, aber ich habe dies aufgrund einer Diskussion zu dieser Frage gemacht: WebAPI-Async-Frage
Wie auch immer, hier ist die beleidigende WebAPI-Methode:
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";
}
Ich hatte bisher geglaubt, dass die zweite Ausnahme erwartet wird, da awaitsie sich nach Abschluss wahrscheinlich in einem anderen Thread befindet, in HttpContext.Currentdem sich eine statische Thread-Variable nicht mehr in den entsprechenden Wert auflöst . Basierend auf dem Synchronisationskontext könnte es nun tatsächlich gezwungen sein, nach dem Warten zum selben Thread zurückzukehren, aber ich mache in meinem Test nichts Besonderes. Dies ist nur eine einfache, naive Verwendung von await.
In Kommentaren in einer anderen Frage wurde mir gesagt, dass sich HttpContext.Currentdas nach einem Warten lösen sollte. Es gibt sogar einen weiteren Kommentar zu dieser Frage, der dasselbe anzeigt. Was ist also wahr? Sollte es sich lösen? Ich denke nein, aber ich möchte eine maßgebliche Antwort darauf, weil asyncund awaitneu genug ist, dass ich nichts Bestimmtes finden kann.
TL; DR: Ist HttpContext.Currentmöglicherweise nullnach einem await?
AspNetSynchronizationContextkümmert sich HttpContextnicht darum await. Darüber hinaus awaitkann (und wird höchstwahrscheinlich) der Fortsetzungsrückruf für einen anderen Thread für das Web-API-Ausführungsmodell erfolgen.
.ConfigureAwait(false)irgendwo auf der ganzen Linie funktioniert hat . Es gibt keine Anfrage oder Steuerung, die explizit über die Geschäftsschicht weitergeleitet wird, da diese nicht webfähig ist. Dies ist beispielsweise für ein Protokollierungsmodul nützlich, das die Anforderungsdetails einfügen kann, wenn die Geschäftslogik ein Generikum schreibt TraceInformation.


