Ich sah eine Nachrichtenwarteschlange wie die Implementierung einer Protokollierungsklasse mit log4net.Ist es erforderlich, async-Protokollierung für ASP.NET MVC mit log4net zu implementieren?
Es ist für ASP.NET MVC Web-Anwendung verwendet wird, so fühle ich mich Threads bereits isoliert sind. Was ist der Vorteil dieser Implementierung?
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;
}
}
}
Das hat nichts mit Isolation zu tun. Wer dies schrieb, wollte nicht auf log4net warten, um die Nachricht zu verarbeiten. Obwohl die Pufferung jede Verzögerung reduzieren würde. Dieser Code ist jedoch * nicht * gut, weil Sie gezwungen sind, einen fest codierten Logger (und einen Singleton nicht weniger!) Zu verwenden, anstatt die Abstraktionen von log4net zu verwenden. Dieser Singleton bricht die Isolation tatsächlich, da er über alle Threads hinweg geteilt werden muss. –
Außerdem hat .NET 4.5 sehr gute gleichzeitige Sammlungen. Wenn Sie ConcurrentQueue verwenden können, müssen Sie Warteschlangen und Sperren nicht verwenden. Dieser Code hat einige ernste Probleme –