Последовательное логирование в отдельном потоке
							
							
						 
						
						
						
						
	
			Ещё одна доработка исходников:
Разгрузка основного потока от логирования.
Возможность изоляции от системных ресурсов, связанных с логированием.
Code
public abstract class BaseLogReceiver<TParent> : BaseLogSource<TParent>, ILogReceiver
	{
		/// <summary>
		/// Инициализировать <see cref="BaseLogReceiver{TParent}"/>.
		/// </summary>
		protected BaseLogReceiver()
		{
		}
		void ILogReceiver.AddLog(LogMessage message)
		{
			LoggingQueue.AddLogAction(()=>RaiseLog(message));
		}
	}
	/// <summary>
	///  Логирование в отдельном параллельном потоке
	/// </summary>
	public class LoggingQueue
	{
		//если понадобится подменять реализацию
		public static LoggingQueue Instance { get; set; }
		static LoggingQueue()
		{
			Instance = new LoggingQueue();
		}
		public LoggingQueue()
		{
			StartThread();
		}
		/// <summary>
		///  Запуск отдельного параллельного потока логирования
		/// </summary>
		protected virtual void StartThread()
		{
			_loggingQueue = new ConcurrentQueue<Action>();
			_waitLog = new AutoResetEvent(false);
			Task.Run(() => DoLoggingListen());
		}
		private ConcurrentQueue<Action> _loggingQueue;
		private AutoResetEvent _waitLog;
		/// <summary>
		///		Добавление записи в лог
		/// </summary>
		/// <param name="action"></param>
		public static void AddLogAction(Action action)
		{
			Instance.AddAction(action);
		}
		/// <summary>
		///  Добавление действия записи в лог в очередь потока логирования
		/// </summary>
		/// <param name="action"></param>
		public virtual void AddAction(Action action)
		{
			_loggingQueue.Enqueue(action);
			_waitLog.Set();
		}
		/// <summary>
		///  Чтение очереди действий логирования
		/// </summary>
		protected virtual void DoLoggingListen()
		{
			do
			{
				Action logAction;
				if (_loggingQueue.TryDequeue(out logAction))
					logAction.Invoke();
				else
					_waitLog.WaitOne();
			} while (!_stopped);
		}
		private bool _stopped;
		/// <summary>
		///  Создание условий окончания работы прослушивания очереди
		/// </summary>
		public virtual void Stop()
		{
			_stopped = true;
			_waitLog.Set();
		}
	}
	/// <summary>
	///  Затычка логирования (может понадобиться для тестирования)
	/// </summary>
	public class LoggingQueueMock: LoggingQueue
	{
		//protected override void DoLoggingListen()
		//{
		//}
		public override void AddAction(Action action)
		{
		}
		protected override void StartThread()
		{
		}
	}
 Кстати, можно что-то придумать и для затыкания LoggingHelper.Now.
Потому что привязка кода к ресурсам системного времени - это совсем не TDD.
--------------------------------------
Критика просто жизненно необходима :)
PS
Беда какая-то с описанием темы. Ломается.