Here is a sample code to explain the approach I am going for.
public class LogWriter
{
#region Private Members
// If writer is not static class, still need to keep single message list; same for other members
private static ConcurrentQueue<string> _logMessages = new ConcurrentQueue<string>();
private static object locker = new object();
private static bool _stopAfterCurrentQueue = false;
private static bool _discardQueueAndStop = false;
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
#endregion
public void Write(string text)
{
if (!_stopAfterCurrentQueue && !_discardQueueAndStop)
{
Task.Run(() =>
{
_logMessages.Enqueue(text);
});
Task.Run(() =>
{
while (!_logMessages.IsEmpty)
{
foreach (var item in _logMessages)
{
_logMessages.TryDequeue(out string current);
lock (locker)
{
// Will be replaced by StreamWriter
File.AppendAllText("Log_" + DateTime.Now.ToString("yyyyMMMdd") + ".txt", current + Environment.NewLine);
}
}
}
}, _tokenSource.Token);
}
}
public void ProcessCurrentAndStop()
{
// Only stops accepting new messages, will process the current queue
_stopAfterCurrentQueue = true;
}
public void DiscardQueueAndStop()
{
// Cancels subsequent Enqueue
_tokenSource.Cancel();
// No more writing even if there is something in the queue
_discardQueueAndStop = true;
}
public void RestartLogging()
{
_stopAfterCurrentQueue = false;
_discardQueueAndStop = false;
_tokenSource.Dispose();
_tokenSource = new CancellationTokenSource();
}
}
The idea is to write to file in asynchronous way. I am trying to make it thread safe as well. There is not much to process here except to write message to a file.
I would like to understand what could be potential issues with this approach and also if it would be better to keep class static.