NLog 中 MappedDiagnosticsLogicalContext 的问题
Problems with MappedDiagnosticsLogicalContext in NLog
我使用 MappedDiagnosticsLogicalContext,因为我需要数据在异步调用中流动。这是我的 NLog.config:
<column name="UserId" layout="${mdlc:item=UserId}" />
但在某些情况下我需要禁用流动,但我不知道该怎么做。例如,我有创建多个线程的代码(见评论):
void Run()
{
logger.Info("Starting threads..."); // MappedDiagnosticsLogicalContext.LogicalThreadDictionary is called and ConcurrentDictionary is created
(new Thread(Func1)).Start(); // both threads will refer to the same ConcurrentDictionary object and share common values, because MappedDiagnosticsLogicalContext stores data in logical call context
(new Thread(Func2)).Start();
}
void Func1()
{
MappedDiagnosticsLogicalContext.Set("UserId", "123");
logger.Info("Some message for Func1");
}
void Func2()
{
Thread.Sleep(5000);
logger.Info("Some message for Func2"); // UserId will be added to the log message here (because it was added in other thread), but I don't need it
}
我找到了肮脏的解决方法:在 Func2() 的开头,我调用
CallContext.FreeNamedDataSlot("NLog.AsyncableMappedDiagnosticsContext")
因此,当在 Func2() 中进行日志记录时,属性 MappedDiagnosticsLogicalContext.LogicalThreadDictionary 的 getter 将创建新的 ConcurrentDictionary,并且线程将具有单独的字典实例。如果在 MappedDiagnosticsLogicalContext class 中有这样的功能就好了。或者有其他一些方法可以解决问题吗?
在 NLog 4.3 中将添加 MappedDiagnosticsLogicalContext.Clear(bool freeDataslot)
,参见 commit。
但是在这种情况下使用 MDC(而不是 MDLC)是否有意义?
我使用 MappedDiagnosticsLogicalContext,因为我需要数据在异步调用中流动。这是我的 NLog.config:
<column name="UserId" layout="${mdlc:item=UserId}" />
但在某些情况下我需要禁用流动,但我不知道该怎么做。例如,我有创建多个线程的代码(见评论):
void Run()
{
logger.Info("Starting threads..."); // MappedDiagnosticsLogicalContext.LogicalThreadDictionary is called and ConcurrentDictionary is created
(new Thread(Func1)).Start(); // both threads will refer to the same ConcurrentDictionary object and share common values, because MappedDiagnosticsLogicalContext stores data in logical call context
(new Thread(Func2)).Start();
}
void Func1()
{
MappedDiagnosticsLogicalContext.Set("UserId", "123");
logger.Info("Some message for Func1");
}
void Func2()
{
Thread.Sleep(5000);
logger.Info("Some message for Func2"); // UserId will be added to the log message here (because it was added in other thread), but I don't need it
}
我找到了肮脏的解决方法:在 Func2() 的开头,我调用
CallContext.FreeNamedDataSlot("NLog.AsyncableMappedDiagnosticsContext")
因此,当在 Func2() 中进行日志记录时,属性 MappedDiagnosticsLogicalContext.LogicalThreadDictionary 的 getter 将创建新的 ConcurrentDictionary,并且线程将具有单独的字典实例。如果在 MappedDiagnosticsLogicalContext class 中有这样的功能就好了。或者有其他一些方法可以解决问题吗?
在 NLog 4.3 中将添加 MappedDiagnosticsLogicalContext.Clear(bool freeDataslot)
,参见 commit。
但是在这种情况下使用 MDC(而不是 MDLC)是否有意义?