Wird die Thread-Identität bei der Verwendung von PLINQ Extensions übertragen?

8

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?

    
Joe Enzminger 29.11.2011, 23:53
quelle

3 Antworten

11

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:

%Vor%

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%     
Drew Marsh 04.12.2011, 20:38
quelle
3

Dies ist die Implementierung hinter CurrentPrincipal

%Vor%

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

    
achitaka-san 30.11.2011 09:33
quelle
1

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.)

    
esteewhy 04.02.2015 13:42
quelle

Tags und Links