using System.Threading; using NLog.Common; using NLog.Targets; using NLog.Targets.Wrappers; namespace NzbDrone.Core.Instrumentation { [Target("SlowRunningAsyncTargetWrapper", IsWrapper = true)] public class SlowRunningAsyncTargetWrapper : AsyncTargetWrapper { private int _state; // 0 = idle, 1 = timer active, 2 = timer active + possibly more work public SlowRunningAsyncTargetWrapper(Target wrappedTarget) : base(wrappedTarget) { } protected override void StopLazyWriterThread() { if (Interlocked.Exchange(ref _state, 0) > 0) { base.StopLazyWriterThread(); } } protected override void Write(AsyncLogEventInfo logEvent) { base.Write(logEvent); if (Interlocked.Exchange(ref _state, 2) <= 0) { // Timer was idle. Starting. base.StartLazyWriterTimer(); } } protected override void StartLazyWriterTimer() { // Is executed when the background task has finished processing the queue. (also executed by base.InitializeTarget once) if (Interlocked.Decrement(ref _state) == 1) { // There might be more work. Restart timer. base.StartLazyWriterTimer(); } } } }