internal static void Write([NotNull] Type loggerType, TargetWithFilterChain targets, LogEventInfo logEvent, LogFactory factory) { if (targets == null) { return; } StackTraceUsage stu = targets.GetStackTraceUsage(); if (stu != StackTraceUsage.None && !logEvent.HasStackTrace) { StackTrace stackTrace; #if !SILVERLIGHT stackTrace = new StackTrace(StackTraceSkipMethods, stu == StackTraceUsage.WithSource); #else stackTrace = new StackTrace(); #endif int firstUserFrame = FindCallingMethodOnStackTrace(stackTrace, loggerType); logEvent.SetStackTrace(stackTrace, firstUserFrame); } ExceptionHandlerContinuation handler; int numberOfTargets = 0; for (var t = targets; t != null; t = t.NextInChain) { FilterResult result = GetFilterResult(t.FilterChain, logEvent); if ((result == FilterResult.Ignore) || (result == FilterResult.IgnoreFinal)) { if (InternalLogger.IsDebugEnabled) { InternalLogger.Debug( "{0}.{1} Rejecting message because of a filter.", logEvent.LoggerName, logEvent.Level); } if (result == FilterResult.IgnoreFinal) { break; } } else { numberOfTargets += 1; } } if (factory.Configuration.PoolingEnabled()) { handler = factory.Configuration.PoolFactory.Get <ExceptionHandlerPool, ExceptionHandlerContinuation>().Get(Thread.CurrentThread.ManagedThreadId, factory.ThrowExceptions); } else { handler = new ExceptionHandlerContinuation(Thread.CurrentThread.ManagedThreadId, factory.ThrowExceptions); } bool clone = numberOfTargets > 1; // Clone a message for each target, so that each target can put it back into the pool when its done with it. for (var t = targets; t != null; t = t.NextInChain) { if (!WriteToTargetWithFilterChain(t, logEvent, handler.Delegate, clone)) { break; } } // No targets at all wanted this log event, so put it back into the pool if (numberOfTargets == 0 || clone) { logEvent.PutBack(); } }