2010-10-01 10 views
27

AKTUALISIERT am 18.11.2014 - Beim Durchsuchen des log4net-Quell-Repositorys habe ich festgestellt, dass die Implementierung von LogicalThreadContext im November 2011 dahingehend geändert wurde, dass sie ihre Eigenschaften mit CallContext.LogicalSetData speichert (und mit LogicalGetData abruft). Dies ist wichtig, da LogicalThreadContext jetzt korrekt funktionieren sollte. Alle in LogicalThreadContext gespeicherten Daten sollten zu allen untergeordneten Threads oder Aufgaben "fließen". Dies steht im Vergleich zu ThreadContext (und der alten Implementierung von LogicalThreadContext), bei der im Kontext gespeicherte Daten für den aktuellen Thread lokal bleiben und NICHT zu untergeordneten Threads/Tasks fließen.Was ist der Unterschied zwischen log4net.ThreadContext und log4net.LogicalThreadContext?

Wenn Sie interessiert sind, hier ist die Änderung:

http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net/Util/LogicalThreadContextProperties.cs?r1=1165341&r2=1207948&diff_format=h

Hoffentlich jemand auf diese alte Frage geschieht wird diese Informationen hilfreich.

log4net stellt zwei verschiedene "Thread-Kontext" -Objekte zur Verfügung: ThreadContext und LogicalThreadContext, von denen jede eine Eigenschaften-Tasche, Eigenschaften, besitzt. ThreadContext hat eine ThreadContextProperties Tasche, während LogicalThreadContext eine LogicalThreadContextProperties Tasche hat.

ThreadContext ist vielleicht häufiger als "MDC" bekannt. LogicalContext ist vielleicht häufiger als "LDC" bekannt. Ich werde den kurzen Namen für den Rest dieses Posts verwenden.

MDC.Properties wird unter Verwendung von System.Threading.Thread.SetData implementiert, während LDC.Properties unter Verwendung von System.Runtime.Remoting.Messaging.CallContext.SetData implementiert wird.

Zum Vergleich zeigt NLog nur "MDC" (jetzt bekannt als MappedDiagnosticContext) an, um lokale Thread-Eigenschaften zu speichern. Die Implementierung von NLog verwendet System.Threading.Thread.SetData. Die Implementierung entspricht der von log4net.

Sowohl in log4net als auch in NLog werden die "MDC" -Eigenschaften in einem Wörterbuch gespeichert, das wiederum im lokalen Thread-Speicher gespeichert wird.

In einem Fall wie diesem wäre das Speichern des Wörterbuchs in einer mit [ThreadStatic] dekorierten Klassenelementvariablen äquivalent?

Was ist die äquivalente (oder ähnliche) Deklaration mit der neuen ThreadLocal Klasse von .NET 4.0?

Was ist der wirkliche, praktische Unterschied zwischen LDC und MDC? Auch nach dem Lesen der oben verlinkten MSDN-Themen ist mir nicht klar. Wann würdest du wirklich eins über dem anderen benutzen? Es scheint, dass die große Mehrheit der Referenzen/Beispiele, die ich für log4net und Kontext sehe, für GDC (global - was ich verstehe), NDC (verschachtelt - was ich auch verstehe) und MDC. Die meisten Referenzen, die ich beim Logging für LDC (oder LogicalThreadContext) finden kann, beziehen sich auf Checkins in den log4net-Quellcode-Repositories, nicht auf die reale Verwendung. LDC kommt fast nie in Fragen oder Beispielen auf.

Ich fandLink, der einige ziemlich gute Informationen über den Unterschied von einem der log4net-Entwickler, Nicko Cadell, bietet, aber es ist mir immer noch nicht klar.

Eine größere Frage, nicht direkt mit log4net verbunden ist, was ist der praktische Unterschied zwischen Thread.SetData und CallContext.SetData?

Nach dem MSDN-Artikel CallContext können CallContext-Daten an eine andere AppDomain weitergegeben werden. Um verbreitet zu werden, muss ein Datenelement, das im CallContext gespeichert ist, die Schnittstelle ILogicalThreadAffinative freilegen. Also, das scheint ein Unterschied zwischen Thread.SetData und CallContext zu sein.

Gemäß der Nicko Cadell-Verknüpfung implementiert log4net ILogicalThreadAffinative nicht, sodass die LDC-Eigenschaften nicht weitergegeben werden.

Vielleicht gibt es hier genug, dass ich meine eigene Frage beantworten könnte, vielleicht nicht. Ich arbeite immer noch am Verständnis.

Wenn Sie log4net verwenden, verwenden Sie alle MDC, LDC, beide? Wenn Sie MDC verwenden, liegt es daran, dass die meisten "realen" Beispiele es zu benutzen scheinen? Wenn Sie LDC verwenden, haben Sie einen bestimmten Verwendungszweck? Wenn Sie beide verwenden, wie wählen Sie wann welche?

Beachten Sie, dass ich einige Artikel über MDC (und vielleicht LDC) möglicherweise nicht richtig in ASP.net-Anwendungen aufgrund von Thread-Switching gesehen habe. Ich bin nicht besonders an diesem Problem interessiert, da ich nicht in ASP.net arbeite.

Eigentlich habe ich ein paar nützliche Beiträge hier auf SO gefunden, die zur Diskussion beitragen könnten:

What are best practices for using thread local storage in .NET?

.Net: Logical thread and Thread Local Storage?

Vielen Dank im Voraus!

Antwort

8

Warnung: Dies ist Vermutung.

Angenommen, Sie schreiben einen Server, und das Bedienen einer Anfrage bedeutet, dass Sie mit einer Reihe verschiedener Dienste sprechen müssen. Da Sie ein durch und durch moderner Entwickler sind, stellen Sie diese Anfragen asynchron und koordinieren, wann alles geantwortet hat (oder abgelaufen ist), um auf die ursprüngliche Anfrage zu antworten.

Das bedeutet, dass die Arbeit, die einer einzelnen Anforderung entspricht, auf viele verschiedene Threads verteilt ist (die Webdienstantworten werden asynchron verarbeitet). Ich verdächtigen, dass CallContext wird verwendet, um die "alles, was ich tue, ist wegen dieser einen eingehenden Anfrage" zu verschiedenen Threads zu verbreiten, so dass Sie alle Protokolle für diese Anfrage zusammen sammeln können. ThreadContext würde da nicht helfen. Beachten Sie, dass ich davon ausgehe, dass die gesamte Arbeit in einer einzigen AppDomain ausgeführt wird, sodass Ihre Probleme dort kein Problem darstellen.

+0

Eigentlich scheint das nicht der Fall zu sein, meine aktuelle Erfahrung mit .NET 4.5 Web API und asynchronen Anfragen ist, dass der CallContext nicht weitergegeben wird, sondern nur auf diesen Aufruf des Threads beschränkt ist. Ich beantwortete einen Thread, der mich hier mit einigen Details führte http://stackoverflow.com/questions/4507968/whats-the-difference-between-log4net-threadlogicalcontext-and-log4net-threadcon –

+0

@TommyG .: Dritter Versuch auf diesen Kommentar :) Es scheint, dass hier mehrere Faktoren im Spiel sind, und sie hängen sowohl von der Version des Frameworks als auch von der Version von log4net ab. Siehe http://stackoverflow.com/questions/9781321/ - es klingt wie 'CallContext' * sollte * funktionieren, aber es gibt (oder war) einen Fehler in log4net, der' LogicalThreadContext' davon abhält, gut damit zu spielen. –

+0

Hallo Jon, das war mein Verständnis des LogicalThreadContext auch von dem Lesen, aber danke, dass du diese andere Frage geteilt hast, das sind gute Informationen. –

Verwandte Themen