我正在使用log4Net来记录活动,在分析了perfmon的堆栈跟踪之后,我发现存在类似场景的死锁,如下所示
ntdll!NtWaitForMultipleObjects+a
KERNELBASE!WaitForMultipleObjectsEx+e1
clr!WaitForMultipleObjectsEx_SO_TOLERANT+62
clr!Thread::DoAppropriateWaitWorker+1e4
clr!Thread::DoAppropriateWait+7d
clr!CLREventBase::WaitEx+c4
clr!AwareLock::EnterEpilogHelper+ca
[[GCFrame]]
clr!AwareLock::EnterEpilog+62
clr!AwareLock::Contention+2a7f4a
clr!JITutil_MonContention+af
[[GCFrame]]
[[HelperMethodFrame] (System.Threading.Monitor.Enter)] System.Threading.Monitor.Enter(System.Object)
log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)+47
log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent)+a8
log4net.Repository.Hierarchy.Logger.CallAppenders(log4net.Core.LoggingEvent)+74
log4net.Repository.Hierarchy.Logger.Log(System.Type, log4net.Core.Level, System.Object, System.Exception)+6a
log4net.Core.LogImpl.InfoFormat(System.String, System.Object)+cc
Archival.Logic.Status(Archival.ProcessArgs)+240
Archival.Logic.Product(Archival.ProcessArgs)+221
Archival.Logic.Number(Archival.ProcessArgs, System.Collections.Generic.IEnumerable`1<LenderProduct>)+2e9
Archival.Logic+<>c__DisplayClass3_0.<ArchiveDealsPerAsset>b__1(System.String)+b5
mscorlib_ni!System.Threading.Tasks.Parallel+<>c__DisplayClass42_0`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].<PartitionerForEachWorker>b__1()+2bd
mscorlib_ni!System.Threading.Tasks.Task.InnerInvokeWithArg(System.Threading.Tasks.Task)+20
mscorlib_ni!System.Threading.Tasks.Task+<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(System.Object)+114
mscorlib_ni!System.Threading.Tasks.Task.Execute()+46
mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+162
mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+14
mscorlib_ni!System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)+21c
mscorlib_ni!System.Threading.Tasks.Task.ExecuteEntry(Boolean)+73
mscorlib_ni!System.Threading.ThreadPoolWorkQueue.Dispatch()+152
clr!CallDescrWorkerInternal+83
clr!CallDescrWorkerWithHandler+4e
clr!MethodDescCallSite::CallTargetWorker+f8
clr!QueueUserWorkItemManagedCallback+2a
clr!ManagedThreadBase_DispatchInner+39
clr!ManagedThreadBase_DispatchMiddle+6c
clr!ManagedThreadBase_DispatchOuter+75
[[DebuggerU2MCatchHandlerFrame]]
clr!ManagedThreadBase_FullTransitionWithAD+2f
clr!ManagedPerAppDomainTPCount::DispatchWorkItem+a0
clr!ThreadpoolMgr::ExecuteWorkRequest+64
clr!ThreadpoolMgr::WorkerThreadStart+f5
clr!Thread::intermediateThreadProc+86
kernel32!BaseThreadInitThunk+22
ntdll!RtlUserThreadStart+34
我初始化记录器
private static readonly ILog logger = LogManager.GetLogger(typeof(Program));
可以采取哪些措施来避免这种情况。 我已经审查了添加每个线程日志的选项。但是,这将是一个过度杀伤,因为我每天将有100个日志。
以下是log4Net的配置:
<log4net>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR"/>
<foreColor value="White"/>
<backColor value="Red"/>
</mapping>
<mapping>
<level value="WARN"/>
<foreColor value="White"/>
<backColor value="Yellow"/>
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] - %message%newline"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO"/>
</filter>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\logfile.txt"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value="yyyyMMdd"/>
<maxSizeRollBackups value="3"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO"/>
</filter>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="ColoredConsoleAppender"/>
<appender-ref ref="RollingLogFileAppender"/>
</root>
答案 0 :(得分:0)
只是猜测发生了什么,出于某种原因,当您想要写入文件时,Logs \ logfile.txt被锁定。第二条日志消息将等待第一条日志消息完成(您的堆栈跟踪)。最小的锁定对你没有帮助,因为你仍然需要锁定文件。如果要访问日志文件,则需要先复制它,然后使用检查工具打开复制的日志文件版本。这样你就可以确定你没有阻止进行想要登录日志文件的进程。