私は "ロギングコンテキスト"を追跡する能力を持っている私が書いたロギングフレームワークを持っています。それはプラグイン可能な戦略フレームワークを持っていますが、最も頻繁に使用するのは、[ThreadStatic]
変数でコンテキストを追跡するThreadStaticバリアントです。私は、マルチスレッドワークフローでのコンテキストのロギングに関する問題を解決しようとしてきました。目標は、共通のスレッドを共有するすべてのメソッドとクラスのすべての呼び出しに対するすべてのログエントリに同じコンテキスト情報を記録させることです。各スレッドは理論的には独自のThreadStatic変数を取得する必要があるため、この考えは簡単に思えました。ThreadStaticデータがスレッド間で予期せず共有されるのはなぜですか?
public class ThreadStaticLoggingContextStrategy: ILoggingContextStrategy
{
public ThreadStaticLoggingContextStrategy()
{
Debug.WriteLine("[INITIALIZE] A new instance of 'ThreadStaticLoggingContextStrategy' has been created.");
}
[ThreadStatic] private LoggingContext _context;
public LoggingContext GetLoggingContext()
{
if (_context == null)
_context = new LoggingContext();
return _context;
}
}
実際、ThreadStaticデータは実際にスレッド間で共有されているようです。これはスレッディングについて理解しているすべてのものに反します。私は、各スレッドがスレッドコンテキストをクリアした(すべてのスレッドがメインループで実行された時を追跡する)余分なログエントリを投げ込むまで、問題の内容を把握するのに苦労していました。コンテキストが初期化され、受信し、そして最後に句の終わりに、そのリセット)は、以下のロギングが一致している:。
[2011-12-15 16:27:21233] [DEBUG] [TPI。 LTI.Eventing.GroupCreatedNotificationHandler: TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.1_Thread: 324]:(CONTEXTID = 184e82dd-152B-4bb5-a2c6-3e05b2365c04; TransactionIdの= 1a11130e-e8dd-4fa1-9107- 3b46dcb4ffd6; HandlerName = GroupCreatedNotificationHandler; http://tpidev.pearsoncmg.com/tpi/lti/service/eventに工具 '0967e031-398f-437d-8949-2a17fe844df0' のイベントをプッシュ HandlerId = WORKDEVELOPMENT.1) ...
[2011-12-15 16:27:21259] [DEBUG] [ TPI.LTI.Facades.LTIFacade: TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.1_Thread: 299]:(CONTEXTID = 184e82dd-152B-4bb5-a2c6-3e05b2365c04; TransactionIdの= 1a11130e-e8dd-4fa1- 9107-3b46dcb4ffd6; HandlerName = GroupCreatedNotificationHandler; HandlerId = WORKDEVELOPMENT.1)ツールのLTIツールインスタンスの取得 instanc電子GUID 0967e031-398f-437d-8949-2a17fe844df0:
[2011-12-15 16:27:21318] [DEBUG] [TPI.LTI.Facades.LTIFacade: TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler .WORKDEVELOPMENT.1_Thread: 299]:(ContextId = 184e82dd-152b-4bb5-a2c6-3e05b2365c04; TransactionId = 1a11130e-e8dd-4fa1-9107-3b46dcb4ffd6; HandlerName = GroupCreatedNotificationHandler; HandlerId = WORKDEVELOPMENT.1)ツールインスタンスのLTIツールインスタンスが見つかりました guid 0967e031-398f-437d-8949-2a17fe844df0。
[2011-12-15 16:27:21352] [DEBUG] [TPI.LTI.Facades.TPIFacade: TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.1_Thread: 299]:(CONTEXTID = 184e82dd-152B-4bb5-a2c6-3e05b2365c04; TransactionIdの= 1a11130e-e8dd-4fa1-9107-3b46dcb4ffd6; れるhandlerName = GroupCreatedNotificationHandler; HandlerId = WORKDEVELOPMENT.1)出版イベントTPIへ 「でhttp:// tpidev。 pearsoncmg.com/tpi/lti/service/event '...
[2011-12-15 16:27:21,428] [DEBUG] [TPI.LTI.Eventing。GroupCreatedNotificationHandler: TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.2_Thread: 301]: [ログ]ログの再設定コンテキスト!
[2011-12-15 16:27:21442] [DEBUG] [TPI.LTI.Eventing.GroupCreatedNotificationHandler: TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.2_Thread: 299]:いいえキューに保留中のメッセージ。 GroupCreatedNotificationHandler.WORKDEVELOPMENT.2ハンドラは...待って ある
[2011-12-15 16:27:22282] [DEBUG] [TPI.LTI.Facades.TPIFacade: TPI.LTI.Provisioning.Handlers。 GroupCreatedNotificationHandler.WORKDEVELOPMENT.1_Thread: 301]:イベントがTPIに公開されました。[2011-12-15 16:27:22283] [DEBUG] [TPI.LTI.Eventing.GroupCreatedNotificationHandler: TPI.LTI.Provisioning.Handlers.GroupCreatedNotificationHandler.WORKDEVELOPMENT.1_Thread: 301]:受信プロバイダからの応答:
この特定のケースでは、1_Threadと2_Threadの2つのスレッドがあります。私は1_Threadのすべてのログエントリの冒頭にインクルードされるはずのコンテキストデータをイタリック体にしました。私は2_Threadのポイントを太字にして、ロギングコンテキストをリセットしました。その時点以降、1_Threadのコンテキスト情報はすべて失われています。今までの数十回のテストでは、ロギングコンテキストが別のスレッドにリセットされた後、すべてのスレッドのコンテキスト情報が失われていました。
私はThreadStaticを誤解していますか?私は2001年からC#コードを書いていますが、以前はこのような現象は経験していませんでした。 .NETの新しいThreadLocal<T>
クラスがあるようですが、とにかくThreadStaticを内部的に使用しているのかどうかは分かりませんし、同じ問題があるのか、それとも機能が異なるのでしょうか。問題は大いに賞賛されるでしょう!ありがとう!
ThreadStaticフィールドを使用しているコードを投稿してください。 –
私は実際にしました。そのかなりストレートフォワード。戦略はシングルトンであり、アプリケーション全体に1つしか存在しません。 – jrista