ASP.NET HttpContext.Current in Task.Run

8

Ich habe ein folgendes Codebeispiel, das in der ASP.NET MVC-Anwendung verwendet wird. Der Zweck dieses Codes besteht darin, eine "Feuer und Vergessen" -Anforderung zum Einreihen in eine lange laufende Operation zu erstellen.

%Vor%

Ich weiß, dass dies keine gute Methode ist, um HttpContext.Current in asynchronem Code zu behandeln, aber unsere Implementierung erlaubt uns derzeit nicht, etwas anderes zu tun. Ich würde gerne verstehen, wie sehr dieser Code gefährlich ist ...

Die Frage: Ist es theoretisch möglich, dass der Kontext auf eine andere Anforderung gesetzt wird, wenn der HttpContext in Task.Run gesetzt wird?

Ich denke ja, aber ich bin mir nicht sicher. Wie ich es verstehe: Request1 wird mit Thread1 aus dem Thread-Pool behandelt, und während Thread1 absolut eine andere Anfrage bearbeitet (Request2), wird der Code innerhalb von Task.Run den Kontext von Request1 zu Request2 setzen.

Vielleicht irre ich mich, aber mein Wissen über ASP.NET-Interna erlaubt es mir nicht, es richtig zu verstehen.

Danke!

    
Alex Dn 26.09.2016, 13:37
quelle

2 Antworten

5

Lassen Sie mich ein wenig Interna auf Sie stoßen:

%Vor%

Also

%Vor%

ist gleich (Pseudocode)

%Vor%

und in deinem Task.Run passiert so etwas

%Vor%

Task.Run startet eine neue Aufgabe mit einem Thread aus dem Thread-Pool. Sie sagen also, dass Ihr neuer Thread "HttpContext property" ein Verweis auf den Startthread "HttpContext property" ist - so weit so gut (gut mit allen NullReference / Dispose-Ausnahmen, denen Sie nach dem Start des Starter-Threads begegnen werden). Problem ist, wenn in Ihrem

%Vor%

Sie haben eine Aussage wie

%Vor%

Sobald Sie auf "Warten" geklickt haben, wird Ihr aktueller Thread in den Thread-Pool zurückgegeben, und nachdem die E / A beendet sind, greifen Sie nach einem neuen Thread aus dem Thread-Pool - fragen Sie sich, was seine "HttpContext-Eigenschaft" ist? Ich weiß es nicht :) Wahrscheinlich enden Sie mit NullReferenceException.

    
Ondrej Svejdar 26.09.2016, 15:44
quelle
2

Das Problem, auf das Sie hier stoßen werden, ist, dass der HttpContext die Anfrage abschließt, wenn die Anfrage abgeschlossen ist. Da Sie nicht auf das Ergebnis von Task.Run warten, erstellen Sie im Wesentlichen eine Race-Bedingung zwischen der Beseitigung des HttpContext und seiner Verwendung innerhalb der Aufgabe.

Ich bin mir ziemlich sicher, dass das einzige Problem, zu dem Ihre Aufgabe führt, eine NullReferenceException oder eine ObjectDisposedException ist. Ich sehe keinen Weg, wo du versehentlich den Kontext einer anderen Anfrage stehlen könntest.

Auch, außer Sie behandeln & amp; Logging Ausnahmen innerhalb Ihrer Aufgabe, Ihr Feuer und vergessen wird werfen und Sie werden nie darüber wissen.

Schauen Sie sich HangFire an oder überlegen Sie, ob Sie eine Nachrichtenwarteschlange für die Verarbeitung von Backend-Jobs aus einem separaten Prozess verwenden möchten.

    
scottt732 26.09.2016 14:33
quelle