Frage

Der Versuch, das neue asynchrone C#-5-Modell zu verwenden, war für mich überraschend AspNetSynchronizationContext ist eine interne Klasse (sowie AspNetSynchronizationContextBase Base).Somit undokumentiert.Es ist jedoch wichtig zu wissen, was es bewirkt, wenn Sie die Async/Await-Funktion in Ihrem ASP.NET-Code verwenden.Bin ich korrigiert, dass es es tut Stellen Sie sicher, dass Ihre Fortsetzungen das Gleiche erhalten HttpContext.Current als ursprüngliche Anrufer?Es nicht garantieren, dass die Fortsetzungen im selben Thread wie die Aufrufer ausgeführt werden?

Wenn die letztere Annahme nicht zutrifft und ich den ursprünglichen Thread erhalte, kann ich dann sicher sein, dass ich in Fortsetzungen denselben Thread-Kontext erhalte?Ich meine Principal/Kultur, die mit dem Thread und dem lokalen Thread-Speicher verbunden ist?Das ist wichtig, da die ASP.NET-Lokalisierung auf der Thread-Kultur basiert und meine Anwendung auf dem .NET-Rollensicherheitsmodell (Thread-Prinzipal) basiert.

War es hilfreich?

Lösung

Liege ich richtig, dass es garantiert, dass Ihre Fortsetzungen denselben HttpContext.Current erhalten wie die ursprünglichen Anrufer?Ist nicht garantiert, dass die Fortsetzungen im selben Thread wie die Aufrufer ausgeführt werden?

Ja, HttpContext.Current bleibt erhalten, und ja, die Fortsetzungen können in einem anderen Thread ausgeführt werden.

Ich meine Principal/Kultur, die mit dem Thread und dem lokalen Thread-Speicher verbunden ist?Das ist wichtig, da die ASP.NET-Lokalisierung auf der Thread-Kultur basiert und meine Anwendung auf dem .NET-Rollensicherheitsmodell (Thread-Prinzipal) basiert.

Der normale Thread-lokale Speicher geht verloren.Sie können dies abmildern, indem Sie verwenden LogicalCallContext (was mit fließt ExecutionContext), aber mit async Es ist einfacher, einfach direkt auf die Variablen zu verweisen.

Der Hauptbetrag bleibt immer erhalten;Andernfalls wäre ein Sicherheitsrisiko gegeben.Das fließt mit ExecutionContext.

Ich glaube, dass die Kultur mitfließt AspNetSynchronizationContext, aber ich habe das noch nicht getestet Die neue Implementierung von .NET 4.5.


Vielleicht finden Sie meine MSDN-Artikel zum Thema SynchronizationContext hilfreich.Es ist keine offizielle Dokumentation (ich arbeite nicht für Microsoft), aber es ist zumindest etwas.Notiere dass der AspNetSynchronizationContext Die in diesem Artikel erwähnte Datei heißt jetzt LegacyAspNetSynchronizationContext in .NET 4.5.

Eine weitere großartige Ressource ist die von Stephen Toub ExecutionContext vs. SynchronizationContext.

Andere Tipps

Nun, während die Erfassung des ExecutionContext immer garantiert ist, hängt die Erfassung und Ausführung der Ausführung auf demselben SynchronizationContext vom Awaiter ab.

Der häufigste Awaiter (der von der GetAwaiter()-Methode zurückgegebene Typ, der intern aufgerufen wird, wenn Sie auf etwas „warten“) ist TaskAwaiter, der von Task.GetAwaiter() zurückgegeben wird.Standardmäßig TaskAwaiter erfasst den aktuellen SynchronizationContext und führt den Fortsetzungsdelegaten für den erfassten SynchronizationContext aus.Das bedeutet, dass Sie HttpContext.Current im Rest Ihrer Methode verwenden können und dass es Ihnen nichts ausmacht, dass es als Fortsetzung ausgeführt wird.Dieser Code funktioniert also wie erwartet (der Teil, in dem Sie „B“ schreiben, wird im selben Synchronisationskontext wie die erste Zeile ausgeführt):

HttpContext.Current.Response.Write("A");
await Task.Delay(1000);
HttpContext.Current.Response.Write("B")

Sie können dieses Verhalten ändern, indem Sie verwenden Task.ConfigureAwait(false) Methode, die den Wartenden anweist, den Rest der Methode nicht zurück zum ursprünglichen SynchronizationContext zu marschieren.

Wenn Sie Task.Run oder Task.Factory.StartNew in der von Ihnen aufgerufenen asynchronen Methode verwenden, liegt es natürlich in Ihrer Verantwortung, den SynchronizationContext erneut zu erfassen.

Viel Glück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top