patterncsharpMinor
Async file writer in .Net 3.5
Viewed 0 times
asyncnetfilewriter
Problem
I'm curious what people think about this little bit of logging code. It seems to work ok. Is there anything I'm missing?
Using Jesse's code, but with
public static class Logger
{
private static readonly object Locker = new object();
private static readonly StreamWriter Writer =
new StreamWriter("c:\\temp\\logtester.log", true) ;
public static void Log(string message)
{
Action action = MessageWriter;
action.BeginInvoke(message, null, null);
}
private static void MessageWriter(string message)
{
lock(Locker)
{
Writer.WriteLine(message);
}
}
}Using Jesse's code, but with
QueueUserWorkItem instead of BeginInvoke.public sealed class Logger : IDisposable
{
private static readonly object Locker = new object();
private static readonly StreamWriter Writer = new StreamWriter("c:\\temp\\logtester.log", true);
private static bool _disposed;
public static void Log(string message)
{
ThreadPool.QueueUserWorkItem(MessageWriter, message);
}
private static void MessageWriter(object message)
{
if (!(message is string)) return;
lock (Locker)
{
Writer.WriteLine(message);
}
}
~Logger()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
lock (Locker)
{
if (_disposed)
return;
if (disposing)
{
if (Writer != null)
Writer.Dispose();
}
_disposed = true;
}
}
}Solution
Here's a slightly different version. It implements
IDisposable so that the StreamWriter can eventually be closed and disposed properly and also uses a typed delegate for asynchronous invocation and properly calls EndInvoke upon completion.public sealed class Logger : IDisposable
{
private delegate void WriteMessage(string message);
private static readonly Logger Instance = new Logger("c:\\temp\\logtester.log");
private readonly object Locker = new object();
private readonly StreamWriter Writer;
private bool Disposed;
private Logger(string logFileName)
{
Writer = new StreamWriter(logFileName, true);
}
~Logger()
{
Dispose(false);
}
public static void Log(string message)
{
WriteMessage action = Instance.MessageWriter;
action.BeginInvoke(message, MessageWriteComplete, action);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private static void MessageWriteComplete(IAsyncResult iar)
{
((WriteMessage)iar.AsyncState).EndInvoke(iar);
}
private void Dispose(bool disposing)
{
lock (Locker)
{
if (Disposed)
{
return;
}
if (disposing)
{
if (Writer != null)
{
Writer.Dispose();
}
}
Disposed = true;
}
}
private void MessageWriter(string message)
{
lock (Locker)
{
if (!Disposed && (Writer != null))
{
Writer.WriteLine(message);
}
}
}
}Code Snippets
public sealed class Logger : IDisposable
{
private delegate void WriteMessage(string message);
private static readonly Logger Instance = new Logger("c:\\temp\\logtester.log");
private readonly object Locker = new object();
private readonly StreamWriter Writer;
private bool Disposed;
private Logger(string logFileName)
{
Writer = new StreamWriter(logFileName, true);
}
~Logger()
{
Dispose(false);
}
public static void Log(string message)
{
WriteMessage action = Instance.MessageWriter;
action.BeginInvoke(message, MessageWriteComplete, action);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private static void MessageWriteComplete(IAsyncResult iar)
{
((WriteMessage)iar.AsyncState).EndInvoke(iar);
}
private void Dispose(bool disposing)
{
lock (Locker)
{
if (Disposed)
{
return;
}
if (disposing)
{
if (Writer != null)
{
Writer.Dispose();
}
}
Disposed = true;
}
}
private void MessageWriter(string message)
{
lock (Locker)
{
if (!Disposed && (Writer != null))
{
Writer.WriteLine(message);
}
}
}
}Context
StackExchange Code Review Q#13248, answer score: 2
Revisions (0)
No revisions yet.