28

2014年11月18日に更新-log4netソースリポジトリを参照しているときに、LogicalThreadContextの実装が2011年11月に変更され、CallContext.LogicalSetDataを使用してプロパティを格納する(そしてLogicalGetDataを使用して取得する)ことがわかりました。これは、LogicalThreadContextが正しく機能するようになることを意味するため重要です。LogicalThreadContextに格納されているデータは、子スレッドまたはタスクに「フロー」する必要があります。これは、コンテキストに格納されたデータが現在のスレッドに対してローカルのままであり、子スレッド/タスクにフローされないThreadContext(およびLogicalThreadContextの古い実装)と比較されます。

興味がある場合は、次の変更があります。

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

うまくいけば、この古い質問に遭遇した誰かがこの情報が役立つと思うでしょう。

log4netは、2つの異なる「スレッドコンテキスト」オブジェクトを提供します 。ThreadContextLogicalThreadContextで、それぞれにプロパティバッグPropertiesがあります。ThreadContextにはThreadContextPropertiesバッグがあり、LogicalThreadContextにはLogicalThreadContextPropertiesバッグがあります。

ThreadContextは、おそらくより一般的に「MDC」として知られています。論理コンテキストは、おそらくより一般的に「LDC」として知られています。この投稿の残りの部分では、短い名前を使用します。

MDC.PropertiesはSystem.Threading.Thread.SetDataを使用して実装され、LDC.PropertiesはSystem.Runtime.Remoting.Messaging.CallContext.SetDataを使用して実装されます。

比較のために、NLogはスレッドローカルプロパティを格納するために「MDC」(現在はMappedDiagnosticContextとして知られています)のみを公開します。NLogの実装はSystem.Threading.Thread.SetDataを使用するため、その実装はlog4netの実装と同じです。

log4netとNLogの両方で、「MDC」プロパティはディクショナリに格納され、ディクショナリ自体はスレッドローカルストレージに格納されます。

このような場合、[ThreadStatic]で装飾されたクラスメンバー変数に辞書を格納することは同等でしたか?

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

.NET 4.0の新しいThreadLocalクラスを使用した同等の(または同様の)宣言は何ですか?

最終的に、LDCとMDCの実際の実用的な違いは何ですか?上記のリンク先のMSDNトピックを読んだ後でも、私にはわかりません。いつ実際に一方を他方の上に使用しますか?log4netとコンテキストで見られる参照/例の大部分は、GDC(グローバル-私が理解している)、NDC(ネストされている-私も理解している)、およびMDCのもののようです。グーグルでLDC(またはLogicalThreadContext)を見つけることができるほとんどの参照は、実際の使用法ではなく、log4netソースコードリポジトリへのチェックインに関連しています。LDCが質問や例で登場することはほとんどありません。

log4net開発者の1人であるNickoCadellとの違いについて、かなり良い情報を提供するこのリンクを見つけましたが、それでも私にはわかりません。

log4netに直接関係しない、より大きな質問は、Thread.SetDataとCallContext.SetDataの実際的な違いは何ですか?

CallContext MSDNの記事によると、CallContextデータは別のAppDomainに伝播できます。伝播するには、CallContextに格納されているデータ項目がILogicalThreadAffinativeインターフェイスを公開する必要があります。つまり、これがThread.SetDataとCallContextの違いの1つであるように思われます。

Nicko Cadellリンクによると、log4netはILogicalThreadAffinativeを実装していないため、LDCプロパティは伝播されません。

たぶん、ここには私自身の質問に答えられるはずの十分なものがあるかもしれませんが、そうではないかもしれません。私はまだ理解に取り組んでいます。

log4netを使用する場合、すべてMDC、LDC、両方を使用しますか?MDCを使用している場合、それは「実世界」の例のほとんどがMDCを使用しているように見えるためですか。LDCを使用している場合、それを使用する特定の理由がありますか?両方を使用する場合、どちらをいつ使用するかをどのように選択しますか?

MDC(およびおそらくLDC)に関するいくつかの記事が、スレッドの切り替えが原因でASP.netアプリケーションで正しく機能しない可能性があることに注意してください。私はASP.netで作業していないため、この問題には特に関心がありません。

実際、私はここSOで、議論に貢献するかもしれないいくつかの有用な投稿を見つけました。

.NETでスレッドローカルストレージを使用するためのベストプラクティスは何ですか?

.Net:論理スレッドとスレッドローカルストレージ?

前もって感謝します!

4

1 に答える 1

8

警告: これは当て推量です。

サーバーを作成していて、リクエストを処理するということは、さまざまなサービスとやり取りする必要があることを意味するとします。完全に最新の開発者であるあなたは、これらのリクエストを非同期で行い、元のリクエストに応答するために、すべての応答 (またはタイムアウト) を調整します。

つまり、1 つの要求に対応する作業が、多くの異なるスレッドに分散されます (Web サービスの応答を非同期的に処理します)。「私がやっていることはすべて、この1つの着信リクエストによるものです」をさまざまなスレッドに伝播するために使用されていると思われます。これにより、そのリクエストのすべてのログをまとめて収集できますそこでは役に立ちません。すべての作業が単一の AppDomain で実行されていると想定しているため、問題はありません。CallContextThreadContext

于 2010-10-01T16:26:00.750 に答える