Created
May 11, 2016 10:39
-
-
Save restlessmedia/3966918fc26b00b9560aaeb055d265b3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class AsyncTraceListener : TraceListener | |
{ | |
public AsyncTraceListener() | |
{ | |
_loggingThread = new Thread(new ThreadStart(ProcessQueue)) | |
{ | |
// this is performed from a bg thread, to ensure the queue is serviced from a single thread | |
IsBackground = true | |
}; | |
_loggingThread.Start(); | |
} | |
public override void Write(string message) | |
{ | |
lock (_queue) | |
{ | |
_queue.Enqueue(() => AsyncWrite(message)); | |
} | |
_hasNewItems.Set(); | |
} | |
public override void WriteLine(string message) | |
{ | |
lock (_queue) | |
{ | |
_queue.Enqueue(() => AsyncWriteLine(message)); | |
} | |
_hasNewItems.Set(); | |
} | |
public override void Flush() | |
{ | |
_waiting.WaitOne(); | |
} | |
protected override void Dispose(bool disposing) | |
{ | |
_terminate.Set(); | |
_loggingThread.Join(); | |
} | |
protected abstract void AsyncWrite(string message); | |
protected abstract void AsyncWriteLine(string message); | |
private void ProcessQueue() | |
{ | |
while (true) | |
{ | |
_waiting.Set(); | |
int i = ManualResetEvent.WaitAny(new WaitHandle[] { _hasNewItems, _terminate }); | |
// terminate was signaled | |
if (i == 1) | |
return; | |
_hasNewItems.Reset(); | |
_waiting.Reset(); | |
Queue<Action> queueCopy; | |
lock (_queue) | |
{ | |
queueCopy = new Queue<Action>(_queue); | |
_queue.Clear(); | |
} | |
foreach (Action fn in queueCopy) | |
{ | |
fn(); | |
} | |
} | |
} | |
private readonly Queue<Action> _queue = new Queue<Action>(); | |
private readonly ManualResetEvent _hasNewItems = new ManualResetEvent(false); | |
private readonly ManualResetEvent _terminate = new ManualResetEvent(false); | |
private readonly ManualResetEvent _waiting = new ManualResetEvent(false); | |
private readonly Thread _loggingThread; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment