2010-10-01 10 views
27

AGGIORNATO il 18/11/2014 - Durante la navigazione nel repository di origine log4net, ho rilevato che l'implementazione di LogicalThreadContext è stata modificata nel novembre 2011 per memorizzare le sue proprietà utilizzando CallContext.LogicalSetData (e ottenerle utilizzando LogicalGetData). Questo è importante perché ciò significa che LogicalThreadContext dovrebbe ora funzionare correttamente. Tutti i dati archiviati in LogicalThreadContext devono essere "trasferiti" su qualsiasi thread o attività figlio. Ciò è paragonabile a ThreadContext (e alla vecchia implementazione di LogicalThreadContext) in cui i dati memorizzati nel contesto rimanevano locali al thread corrente e NON venivano trasferiti ai thread/attività secondari.Qual è la differenza tra log4net.ThreadContext e log4net.LogicalThreadContext?

Se siete interessati, qui è il cambiamento:

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

Speriamo che qualcuno accadendo su questa vecchia domanda troveranno utili queste informazioni.

log4net fornisce due diversi oggetti "contesto di thread": ThreadContext e LogicalThreadContext, ognuno dei quali ha un sacchetto di proprietà, Proprietà. ThreadContext ha una borsa ThreadContextProperties mentre LogicalThreadContext ha una borsa LogicalThreadContextProperties.

ThreadContext è forse più comunemente noto come "MDC". LogicalContext è forse più comunemente noto come "LDC". Userò il nome breve per il resto di questo post.

MDC.Properties viene implementato utilizzando System.Threading.Thread.SetData mentre LDC.Properties viene implementato utilizzando System.Runtime.Remoting.Messaging.CallContext.SetData.

Per confronto, NLog espone solo "MDC" (ora noto come MappedDiagnosticContext) per memorizzare le proprietà locali del thread. L'implementazione di NLog utilizza System.Threading.Thread.SetData, quindi la sua implementazione è uguale a quella di log4net.

Sia in log4net che in NLog, le proprietà "MDC" sono memorizzate in un dizionario che è memorizzato nella memoria locale del thread.

In un caso come questo, il salvataggio del dizionario in una variabile membro della classe decorata con [ThreadStatic] è stato equivalente?

[ThreadStatic] 
private static IDictionary<string, string> threadProperties; 

Quale sarebbe la dichiarazione equivalente (o simile) che utilizza la nuova classe ThreadLocal di .NET 4.0?

In definitiva, qual è la reale, pratica, differenza tra LDC e MDC? Anche dopo aver letto gli argomenti MSDN collegati sopra, non mi è chiaro. Quando useresti davvero uno sull'altro? Sembra che la stragrande maggioranza dei riferimenti/esempi che vedo per log4net e il contesto sia per GDC (globale - che capisco), NDC (nidificato - che capisco anche io) e MDC. La maggior parte dei riferimenti che posso trovare su LDC (o LogicalThreadContext) durante il google sono relativi ai checkin negli archivi del codice sorgente log4net, non all'utilizzo reale. LDC non compare quasi mai in domande o esempi.

Ho trovato il collegamento this che offre alcune informazioni piuttosto buone sulla differenza da uno degli sviluppatori di log4net, Nicko Cadell, ma non è ancora chiaro per me.

Una domanda più grande, non direttamente correlata a log4net, qual è la differenza pratica tra Thread.SetData e CallContext.SetData?

Secondo l'articolo MSDN CallContext, i dati di CallContext possono essere propagati a un altro AppDomain. Per essere propagato, un elemento di dati memorizzato in CallContext deve esporre l'interfaccia ILogicalThreadAffinative. Quindi, sembra che ci sia una differenza tra Thread.SetData e CallContext.

In base al collegamento Nicko Cadell, log4net non implementa ILogicalThreadAffinative, quindi le proprietà LDC non verranno propagate.

Forse c'è abbastanza qui che dovrei essere in grado di rispondere alla mia domanda, forse no. Sto ancora lavorando per capire.

Se si utilizza log4net, si utilizzano MDC, LDC, entrambi? Se usi MDC, è perché la maggior parte degli esempi del "mondo reale" sembra usarlo? Se usi LDC, hai un motivo specifico per usarlo? Se usi entrambi, come scegli quando usare quale?

Nota che alcuni articoli relativi a MDC (e forse LDC) potrebbero non funzionare nelle applicazioni ASP.net a causa del cambio di thread. Non sono particolarmente interessato a questo problema perché non sto lavorando in ASP.net.

In realtà, ho trovato un paio di post utili qui, in modo che possa essere utile alla discussione:

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

.Net: Logical thread and Thread Local Storage?

Grazie in anticipo!

risposta

8

Attenzione: questo è un tentativo.

Supponiamo che tu stia scrivendo un server e, a seguito di una richiesta, devi parlare con una serie di servizi diversi. Essendo uno sviluppatore completamente moderno, tu fai queste richieste in modo asincrono, coordinando quando tutto è risposto (o scaduto) al fine di rispondere alla richiesta originale.

Ciò significa che il lavoro corrispondente a una singola richiesta è suddiviso tra molti thread diversi (elaborazione delle risposte del servizio Web in modo asincrono). I sospetto che CallContext viene utilizzato per propagare il "tutto ciò che sto facendo è a causa di questa una richiesta in entrata" a thread diversi, in modo che è possibile raccogliere tutti i registri per tale richiesta insieme. ThreadContext non sarebbe d'aiuto. Tieni presente che suppongo che tutto il lavoro venga eseguito in un singolo AppDomain, quindi la tua preoccupazione non sarebbe un problema.

+0

In realtà non sembra essere il caso, la mia attuale esperienza con .net 4.5 web api e richieste asincrone è che il CallContext non è passato, piuttosto è limitato solo a quella invocazione del thread. Ho risposto a una discussione che mi ha condotto qui con alcuni dettagli http://stackoverflow.com/questions/4507968/whats-the-difference-between-log4net-threadlogicalcontext-and-log4net-threadcon –

+0

@TommyG .: Terzo tentativo in questo commento :) Sembra che ci siano più fattori in gioco qui e dipendono sia dalla versione del framework che dalla versione di log4net. Vedi http://stackoverflow.com/questions/9781321/ - sembra che "CallContext' * dovrebbe * funzionare, ma c'è (o c'era) un bug in log4net che impedisce a" LogicalThreadContext "di giocare bene con esso. –

+0

Ciao Jon, ho capito anche il LogicalThreadContext dalla lettura, ma grazie per aver condiviso quell'altra domanda, questa è una buona informazione. –

Problemi correlati