私はlog4netでログクラスの実装のようなメッセージキューを見た。log4netでASP.NET MVCの非同期ロギングを実装する必要はありますか?
これは、ASP.NET MVC Webアプリケーションに使用するので、私はスレッドがすでに隔離されていると感じています。この実装のメリットは何ですか?
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;
}
}
}
これはアイソレーションとは何の関係もありません。誰でもこれを書いた人は、log4netがメッセージを処理するのを待つことを望んでいませんでした。ただし、バッファリングは遅延を低減します。このコードは、log4netの抽象構文を使用する代わりに、ハードコードされたロガー(およびシングルトン以下)を使用する必要があるため、このコードは優れていません。それはまた、.NET 4.5は非常に良い同時コレクションを持ってい –
すべてのスレッド間で共有する必要があるとして、実際にこのシングルトンは孤立を破ります。 ConcurrentQueueを使用できるときは、キューとロックを使用する必要はありません。そのコードには深刻な問題がいくつかあります –