I have a logging class in which I spawn a Task to append all messages from a BlockingCollection<string>
to the log file, sleep two seconds, and repeat infinitely, until the fifo is completed.
This works fine for local files, but when writing to a slow network drive I'm getting intermittent failures at using (StreamWriter sw)
: IOException - The process cannot access the file 'x.txt' because it is being used by another process.
I am not writing to the same file from two threads. There are 3-4 instances of my logger going, but each instance has a unique filename based on timestamp and guid. No external apps are accessing these files at the time.
Even though the StreamWriter is disposed by the using-block in the first trip through the while loop and I sleep for a while, the second trip through the while loop somehow still finds the file to be open at some lower level (The stack trace gets down to System.IO.FileStream.Init
, and ultimately, System.IO.__Error.WinIOError
.
I can intermittently, sometimes, reproduce the exception in a simple integration test that spins up 100 logger objects in a Parallel.For loop.
private void FlushFifoToLogFile()
{
while (!_fifoLog.IsCompleted)
{
if (_fifoLog.Count > 0)
{
using (StreamWriter sw = new StreamWriter(_logFilePath, append:true))
{
while (_fifoLog.TryTake(out string line))
{
sw.WriteLine(line);
}
}
}
_flushCts.Token.WaitHandle.WaitOne(SLEEP_MILLISECONDS);
}
}