2012-05-11 9 views
5

Ich stieß heute auf ein seltsames Problem, das für mich keinen Sinn ergab. Hier eine Zusammenfassung:System.Web.HttpContext.Current Nullen selbst nach der Überprüfung für einen Cache

innerhalb einer Methode, überprüfe ich für einen Cache gespeicherten Artikel wie folgt:

private async Task<RatesStatus> getRatesStatusAsync() { 

    //... 

    if (_currentHttpContext != null) { 

     //Here, I am checking for a Cached item 
     var cachedRatesStatusObj = HttpContext.Current.Cache[Constants.RATESSTATUS_CACHE_KEY_NAME]; 
     if (cachedRatesStatusObj != null) 
      return (RatesStatus)cachedRatesStatusObj; 
    } 

    //... 

    cacheRatesStatusObject(ratesStatus); 

    //... 
} 

Hier ist die HttpContext.Current nicht null ist, wie innerhalb einer ASP.NET-Anwendung erwartet. Dann in der cacheRatesStatusObject Methode, ich überprüfen, ob HttpContext.Current null ist oder nicht, wie unten:

private void cacheRatesStatusObject(RatesStatus ratesStatus) { 

    //... 

    //Seeing if HttpContext.Current is null or not first. 
    //and it is null here... 
    if (HttpContext.Current == null) 
     return; 

    //... 
} 

Und es ist dort null. Keine Ahnung, was hier passiert. Irgendwelche Gedanken?

+1

bemerkte ich Ihre Methode 'async' gekennzeichnet ist. Nur um sicher zu sein, wo auch immer Sie diese Methode aufrufen, Sie tun ein "warten" irgendwo, bevor die "Antwort" zurück zum Client gesendet und geschlossen wird, richtig? Andernfalls könnte es sich nur um eine Wettlaufsituation handeln, bei der die "Antwort" zurückgegeben und entsorgt wird, bevor sie zu dieser Linie gelangt, aber immer noch in der Linie oben verfügbar ist. –

+0

@GuthMD Ja, ich habe irgendwo innerhalb der Methode "erwarten". Das muss das Problem sein. – tugberk

Antwort

4

Wenn Sie async/await verwenden, markiert der Thread, der die Anfrage bearbeitet, die Anfrage als unvollständig und kehrt dann zu ASP.NET thread pool zurück. Wenn das Erwartete später abgeschlossen wird, wird ein anderer Thread zugewiesen, um den Rest der Methode auszuführen, jedoch wird HttpContext nicht über Threads migriert. Deshalb erhalten Sie beim Aufruf der Warte-Methode eine Null-Referenz.

Sie können eine Referenz des Httpcontext an die await Methode, so etwas wie dies passieren:

await cacheRatesStatusObject(HttpContext.Current, ratesStatus); 

aber Sie sollten sehr vorsichtig sein mit Nebenläufigkeit und Rennbedingungen, zum Beispiel den Umgang, wenn das await Thread sperrt eine Ressource und ein anderer Anfrage-Thread versucht es zu benutzen, dann wird Ihr Thread-Pool boomen. Die meisten Menschen lösen dies, indem sie neue Objekte erstellen und sie an parameterisierte Threads übergeben, anstatt einen Verweis von HttpContext über Threads zu übergeben.

+0

Eigentlich ist 'HttpContext.Current' nach dem Warten nicht null. Es ist nur null in der asynchronen Methode. Siehe diese Frage: http://aspnetwebstack.codeplex.com/discussions/359012 – Aliostad

0

Es wird nicht selbst ungültig.

Die HttpContext wird nur in einer "thread statischen" Weise gespeichert.

Wie von der anderen Antwort vorgeschlagen, übergeben Sie einfach die Instanz.

+0

Ja, ich habe gerade herausgefunden. Ich bekomme eine Instanz davon vor dem asynchronen Aufruf: 'var httpContext = HttpContext.Current;' Später arbeite ich dann mit dieser lokalen Variable. – tugberk

+0

Das macht nicht viel Sinn. Warum wird der Thread-Kontext nicht kopiert? – Aliostad

+0

@Aliostad: Es ist nur so, wie es funktioniert. Sonst würden andere Threads, die andere Anforderungen bedienen, den gleichen Status haben. – leppie