【问题标题】:NLog hangs in trace (multithreading issue?)NLog 在跟踪中挂起(多线程问题?)
【发布时间】:2012-08-17 12:49:51
【问题描述】:

症状是应用程序挂起(托管在 IIS 7 中) 附加调试时发现有大约 100 个线程具有这样的堆栈:

NLog.dll!NLog.Targets.Target.WriteAsyncLogEvent(NLog.Common.AsyncLogEventInfo logEvent) + 0x54 bytes     
NLog.dll!NLog.LoggerImpl.WriteToTargetWithFilterChain(NLog.Internal.TargetWithFilterChain targetListHead, NLog.LogEventInfo logEvent, NLog.Common.AsyncContinuation onException) + 0x8b bytes    
NLog.dll!NLog.LoggerImpl.Write(System.Type loggerType, NLog.Internal.TargetWithFilterChain targets, NLog.LogEventInfo logEvent, NLog.LogFactory factory) + 0xee bytes    
NLog.dll!NLog.Logger.WriteToTargets(NLog.LogLevel level, string message, object[] args) + 0x14 bytes     
NLog.dll!NLog.Logger.Trace<System.__Canon,long>(string message, System.__Canon argument1, long argument2) + 0x90 bytes
... <my app code> ...

与

mscorlib.dll!System.Collections.Generic.Dictionary<NLog.Layouts.Layout,string>.FindEntry(NLog.Layouts.Layout key) + 0xd0 bytes   
mscorlib.dll!System.Collections.Generic.Dictionary<System.__Canon,System.__Canon>.TryGetValue(System.__Canon key, out System.__Canon value) + 0x14 bytes     
NLog.dll!NLog.Layouts.SimpleLayout.GetFormattedMessage(NLog.LogEventInfo logEvent) + 0x81 bytes  
NLog.dll!NLog.Targets.FileTarget.GetBytesToWrite(NLog.LogEventInfo logEvent) + 0x1c bytes    
NLog.dll!NLog.Targets.FileTarget.Write(NLog.Common.AsyncLogEventInfo[] logEvents) + 0x308 bytes  
NLog.dll!NLog.Targets.Target.WriteAsyncLogEvents(NLog.Common.AsyncLogEventInfo[] logEvents) + 0x258 bytes    
NLog.dll!NLog.Targets.Wrappers.AsyncTargetWrapper.ProcessPendingEvents(object state) + 0x1e6 bytes   
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0xdc bytes     
mscorlib.dll!System.Threading._TimerCallback.PerformTimerCallback(object state) + 0x97 bytes     
... <my app code> ...

和一个

mscorlib.dll!System.Collections.Generic.Dictionary<NLog.Layouts.Layout,string>.Insert(NLog.Layouts.Layout key, string value, bool add) + 0x1e0 bytes     
NLog.dll!NLog.LogEventInfo.AddCachedLayoutValue(NLog.Layouts.Layout layout, string value) + 0x6c bytes   
NLog.dll!NLog.Layouts.Log4JXmlEventLayout.GetFormattedMessage(NLog.LogEventInfo logEvent) + 0xf5 bytes   
NLog.dll!NLog.Targets.Target.PrecalculateVolatileLayouts(NLog.LogEventInfo logEvent) + 0xb8 bytes    
NLog.dll!NLog.Targets.Wrappers.AsyncTargetWrapper.Write(NLog.Common.AsyncLogEventInfo logEvent) + 0x23 bytes     
NLog.dll!NLog.Targets.Target.WriteAsyncLogEvent(NLog.Common.AsyncLogEventInfo logEvent) + 0x151 bytes    
NLog.dll!NLog.LoggerImpl.WriteToTargetWithFilterChain(NLog.Internal.TargetWithFilterChain targetListHead, NLog.LogEventInfo logEvent, NLog.Common.AsyncContinuation onException) + 0x8b bytes    
NLog.dll!NLog.LoggerImpl.Write(System.Type loggerType, NLog.Internal.TargetWithFilterChain targets, NLog.LogEventInfo logEvent, NLog.LogFactory factory) + 0xee bytes    
NLog.dll!NLog.Logger.WriteToTargets(NLog.LogLevel level, string message, object[] args) + 0x14 bytes     
NLog.dll!NLog.Logger.Debug<Werp.Controller.Common.Interfaces.EntityEventAction,System.__Canon>(string message, Werp.Controller.Common.Interfaces.EntityEventAction argument1, System.__Canon argument2) + 0x8d bytes     
... <my app code> ...

这种情况有时会发生,可能是一周一次,我没有精确的场景来重现它。

我该如何解决这个问题?它是 NLog 中的错误,还是我的一些误用或错误配置?

【问题讨论】:

    标签: c# .net multithreading logging nlog


    【解决方案1】:

    Dictionary&lt;T&gt; 不是线程安全的,所以在多个线程中访问它可能会导致这样的问题,

    http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

    http://blogs.msdn.com/b/asiatech/archive/2009/05/11/100-cpu-caused-by-system-collections-generic-dictionary.aspx

    很难说您是否可以将 NLog 配置为在多线程中工作。你尝试过使用它的 AsyncWrapper 吗?

    http://nlog-project.org/wiki/AsyncWrapper_target

    根据NLog论坛,使用异步方式应该可以解决问题,

    http://nlog-forum.1685105.n2.nabble.com/Multi-Threading-in-NLog-td3728834.html

    【讨论】:

    • 感谢参与,我的配置已经包含 这是异步包装器的快捷方式
    • 那么这几乎是开发人员应该修复的错误。你去nlog.codeplex.com/workitem/list/basic报告这个问题了吗?
    【解决方案2】:

    我最近遇到了同样的问题——WriteAsyncLogEvent 上的很多线程阻塞。我没有任何Dictionary 线程。我有一个线程卡在AsyncRequestQueue.Enqueue 中,您可能在线程列表中错过了它。

    就我而言,问题在于AsyncWrapper 上的overflowAction 被设置为...Block!将其设置为Discard 是处理过载记录器的更明智的方法。

    有时日志消息会累积,而不是 NLog 本身的错误。有时该进程因其他原因(磁盘阻塞、大量交换、防病毒混乱、完整 GC)而被卡住。然后,线程列表包含许多卡在 NLog 上的线程,仅仅是因为 NLog 恰好依赖于相同的重载资源。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 2019-07-08
      • 1970-01-01
      相关资源
      最近更新 更多