Ich verwende .AsParallel (). ForAll (), um eine Auflistung im Kontext einer ASP.NET-Anforderung parallel aufzuzählen. Die Aufzählungsmethode basiert auf System.Threading.Thread.CurrentPrincipal.
Kann ich mich auf die einzelnen Threads verlassen, deren System.Threading.Thread.CurrentPrincipal auf den HttpContext.Current.User des Threads gesetzt wurde, der die ASP.NET-Anfrage verarbeitet, oder muss ich das selbst verwalten?
Eine weitere Möglichkeit, die Frage zu stellen, ist, ob die von PLINQ verwendeten Threads die Identität des Threads erben, der die Operation aufgerufen hat?
Nein, die Identität wird nicht automatisch an diese Worker-Threads weitergegeben. Wenn die von Ihnen verwendeten Komponenten HttpContext.User
sind, können Sie die aktuelle Instanz "% ambient" HttpContext
in Ihrem Hauptthread erfassen und an Ihre Worker-Threads weitergeben. Das würde ungefähr so aussehen:
Das funktioniert, weil HttpContext.Current
von einem Thread-Static unterstützt wird, so dass jedem Worker-Thread die Instanz aus Ihrem Haupt-Thread zugewiesen wird und jede Arbeit, die von diesem Punkt an ausgeführt wird, wird dies als aktuelle Instanz sehen.
Nun müssen Sie sich bewusst sein, dass HttpContext
und die zugehörigen Klassen nicht threadsicher sind, also ist das ein bisschen ein Hack. Wenn Sie nur von Immobilien lesen, ist das nicht wirklich ein Problem. Wenn Sie keine Komponenten verwenden, die auf HttpContext.Current
angewiesen sind, wäre es "sauberer", das nicht zu setzen und stattdessen die erfasste currentHttpContext
-Variable direkt im Worker zu verwenden.
Wenn Sie wirklich nur den aktuellen Principal zu den Worker-Threads weiterleiten müssen, können Sie genau das tun, indem Sie denselben Ansatz verwenden:
%Vor% Dies ist die Implementierung hinter CurrentPrincipal
Alle neu erstellten Threads haben null und werden aus der Anwendungsdomäne übernommen. Also sollte es in Ordnung sein. Trotzdem müssen Sie vorsichtig mit Kultur sein. Es wird nicht vom Startthread abgeleitet. Siehe: Parallele Programmierung, PLINQ und Globalisierung
Eine feine Sache, die man beim Übergeben von Principal durch die Grenze .AsParallel () beachten sollte: Wo wird Ihre Sequenz materialisiert?
Dies ist kein Problem mit .ForAll () , aber betrachten Sie ein anderes Szenario:
%Vor%Dann übergeben Sie result an einer anderen Stelle, so dass es die Thread-Grenze überschreitet (was wahrscheinlich ist, wenn Sie es aus der WCF-Aktionsmethode zurückgeben).
In diesem Fall, wenn MyTransform angewendet wird, kann der Wert für Thread. CurrentPrincipal etwas unerwartetes enthalten.
Die Problemumgehung besteht also darin, die Abfrage sofort zu materialisieren (durch Aufrufen von .ToArray () , .ToList () usw.)
Tags und Links c# multithreading asp.net plinq