J'ai vu une implémentation de file d'attente de messages comme une classe de journalisation avec log4net.
Il est utilisé pour une application web ASP.NET MVC, donc je pense que les fils sont déjà isolés. Quel est l'avantage de cette mise en œuvre ?
public class Logger
{
private ILog _logger;
private static Logger _instance;
private Queue<Action> _logQueue = new Queue<Action>();
private ManualResetEvent _newItemsExist = new ManualResetEvent(false);
private ManualResetEvent _terminate = new ManualResetEvent(false);
private ManualResetEvent _waiter = new ManualResetEvent(false);
private static object _syncLock = new object();
private Thread _logThread;
public enum LoggingType { Debug, Info, Warn, Error, Fatal };
public Logger()
{
_logger = LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
_logThread = new Thread(new ThreadStart(ProcessQueue));
_logThread.IsBackground = true;
_logThread.Start();
}
public static Logger Instance
{
get
{
if (_instance == null)
lock (_syncLock)
if (_instance == null)
_instance = new Logger();
return _instance;
}
}
private void ProcessQueue()
{
while (true)
{
_waiter.Set();
int i = ManualResetEvent.WaitAny(new WaitHandle[] { _newItemsExist, _terminate });
if (i == 1) return;
_newItemsExist.Reset();
_waiter.Reset();
Queue<Action> queueCopy;
lock (_logQueue)
{
queueCopy = new Queue<Action>(_logQueue);
_logQueue.Clear();
}
foreach (Action logAction in queueCopy)
logAction();
}
}
public void _LogMessage(string msg_, Exception inEx_, LoggingType type_)
{
lock (_logQueue)
_logQueue.Enqueue(() => AsyncLogMessage(msg_, inEx_, type_));
_newItemsExist.Set();
}
private void AsyncLogMessage(string msg_, Exception inEx_, LoggingType type_)
{
switch (type_)
{
case LoggingType.Debug:
_logger.Debug(msg_, inEx_);
break;
case LoggingType.Info:
_logger.Info(msg_, inEx_);
break;
case LoggingType.Warn:
_logger.Warn(msg_, inEx_);
break;
case LoggingType.Error:
_logger.Error(msg_, inEx_);
break;
case LoggingType.Fatal:
_logger.Fatal(msg_, inEx_);
break;
}
}
}