123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- using System;
- using System.Collections.Generic;
- using System.Threading;
- namespace Wayne.Lib.Log
- {
- internal class LoggerThread : IDisposable
- {
- #region Fields
- private readonly Thread thread;
- private readonly AutoResetEvent waitEvent;
- private readonly Queue<LogEntry> entryQueue = new Queue<LogEntry>();
- private readonly object entryQueueLock = new object();
- private readonly object logWritingLock = new object();
- private bool threadShouldExit; // Flag that is used to indicate to the thread that it should exit gracefully.
- private bool disposed;
- private readonly LogConfig logConfig;
- #endregion
- #region Construction & Finalizer
- /// <summary>
- /// Initializes a new instance of the Logger thread and starts it.
- /// </summary>
- /// <param name="logType"></param>
- /// <param name="logConfig"></param>
- public LoggerThread(LogType logType, LogConfig logConfig)
- {
- this.logConfig = logConfig;
- //Create the wait event
- waitEvent = new AutoResetEvent(false);
- //Create the thread.
- thread = new Thread(Execute) { Priority = ThreadPriority.Lowest };
- switch (logType)
- {
- case LogType.Debug:
- thread.Name = "Debug Logger thread";
- break;
- case LogType.Event:
- thread.Name = "Event Logger thread";
- break;
- }
- thread.IsBackground = true;
- thread.Start();
- }
- /// <summary>
- /// Finalizer
- /// </summary>
- ~LoggerThread()
- {
- Dispose(false);
- }
- #endregion
- #region IDisposable Members
- /// <summary>
- /// Disposes the resources owned by the logger thread.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <summary>
- /// Internal dispose method.
- /// </summary>
- /// <param name="disposing"></param>
- private void Dispose(bool disposing)
- {
- if (!disposed)
- {
- disposed = true;
- if (disposing)
- {
- threadShouldExit = true;
- waitEvent.Set();
- waitEvent.Close();
- thread.Join();
- }
- }
- }
- #endregion
- #region The thread method
- /// <summary>
- /// The main function for the logger thread.
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")]
- private void Execute()
- {
- while (!threadShouldExit)
- {
- try
- {
- // Wait for an event.
- waitEvent.WaitOne();
- if (!disposed)
- {
- // Clear the entry queue.
- bool queueEmpty;
- do
- {
- // Pick the next logEntry in the queue safely in a locked way.
- LogEntry logEntry = null;
- lock (entryQueueLock)
- {
- if (entryQueue.Count > 0)
- logEntry = entryQueue.Dequeue();
- queueEmpty = (entryQueue.Count == 0);
- }
-
- // Was there a log entry for me?
- if (!disposed && (logEntry != null))
- PerformLog(logEntry);
- }
- while (!queueEmpty);
- }
- }
- catch (Exception exception)
- {
- Logger.FireOnThreadException(new LogException(LogExceptionType.GeneralThreadException,
- "An Exception is caught in the Logger.Execute() method. See inner exception!", exception));
- }
- #if WindowsCE
- catch
- {
- Logger.FireOnThreadException(new LogException(LogExceptionType.GeneralThreadException,
- "An unknown exception is caught in the Logger.Execute() method."));
- }
- #endif
- }
- }
- /// <summary>
- /// Performs the actual logging.
- /// </summary>
- /// <param name="logEntry"></param>
- private void PerformLog(LogEntry logEntry)
- {
- lock (logWritingLock)
- {
- LogWriter[] logWriters;
- DebugMarkerLogEntry debugMarkerLogEntry = logEntry as DebugMarkerLogEntry;
- if (debugMarkerLogEntry != null)
- {
- // Get all active LogWriters.
- logWriters = logConfig.GetLogWriters();
- }
- else
- {
- // Get a list of the LogWriters that wants to log this entry.
- logWriters = logConfig.GetLogWriters(logEntry.EntityCategory);
- }
- // Call them in turn and write the log entry.
- foreach (LogWriter writer in logWriters)
- writer.Write(logEntry);
- }
- }
- #endregion
- #region Public Methods
- /// <summary>
- /// Adds an entry that should be handled by the logger thread.
- /// </summary>
- /// <param name="logEntry"></param>
- public void AddEntry(LogEntry logEntry)
- {
- if (disposed)
- return;
- if (Logger.Synchronized)
- {
- PerformLog(logEntry);
- }
- else
- {
- lock (entryQueueLock)
- {
- entryQueue.Enqueue(logEntry);
- }
- waitEvent.Set();
- }
- }
- #endregion
- }
- }
|