Skip to content

Instantly share code, notes, and snippets.

@KarolisKaj
Last active July 28, 2018 04:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KarolisKaj/e48eccb72a0ec21b93d1f7068b9321c0 to your computer and use it in GitHub Desktop.
Save KarolisKaj/e48eccb72a0ec21b93d1f7068b9321c0 to your computer and use it in GitHub Desktop.
Idea to implement event pump for logging
public class LoggerContext : IDisposable
{
private readonly Thread _contextPump;
private readonly ManualResetEventSlim _resetHandle = new ManualResetEventSlim(false);
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private ConcurrentQueue<Action> _logsQueue = new ConcurrentQueue<Action>();
private readonly bool _flush;
public LoggerContext(bool flush = false)
{
_flush = flush;
_contextPump = new Thread(new ThreadStart(Pump)) { IsBackground = !flush };
_contextPump.Start();
}
private void Pump()
{
while (true)
{
try
{
while (_logsQueue.TryDequeue(out var action))
action?.Invoke();
_resetHandle.Wait(_cts.Token);
_resetHandle.Reset();
}
catch { }
try
{
if ((_flush || _logsQueue.IsEmpty) || (_cts.IsCancellationRequested && !_flush)) return;
}
catch { if (!_flush || (_flush || _logsQueue.IsEmpty)) return; }
}
}
/// <exception cref="ObjectDisposedException">Thrown when dispose was already called on an object.</exception>
public void Execute(Action action)
{
if (_cts.IsCancellationRequested) throw new ObjectDisposedException(typeof(LoggerContext).Name);
_logsQueue.Enqueue(action);
_resetHandle.Set();
}
#region IDisposable Support
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_cts.Cancel();
_resetHandle.Set();
_contextPump.Join();
_resetHandle.Dispose();
_cts.Dispose();
}
disposedValue = true;
}
}
public void Dispose() => Dispose(true);
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment