Reputation: 8971
I have a function that asynchronously writes to a log file, that is called multiple times. However, I'm getting an error:
System.IO.IOException: 'The process cannot access the file '<log path>' because it is being used by another process.'
The code is here:
public async void log(string msg)
{
await Task.Run(() => {
// Check that log directory exists, or create one
if (!Directory.Exists(@"log dir")) Directory.CreateDirectory(@"log dir");
// Append to log
using (StreamWriter w = File.AppendText(@"log path"))
{
w.WriteLine(DateTime.Now + " : " + msg);
w.Close();
}
});
}
My understanding of async programming comes mainly from node.js, which is a single-threaded language. Am I correct in thinking that since C# is multi-threaded (and takes a multi-threaded approach to async code) that IO doesn't automatically queue for a resource as it does in node.js?
Is there an easy way to write to files asynchronously in C#? Or am I better off just making this log function synchronous, since the performance cost would be irrelevant for a few line writes...
Upvotes: 2
Views: 1369
Reputation: 21033
Async Void is bad you will not catch exceptions properly, also by using task run with synchronous methods you aren't getting the full benefits of Async, you will still be blocking resources.
It's probably better to use a logging framework but if you really want you can write async like so:
private async Task WriteTextAsync(string filePath, string text)
{
byte[] encodedText = Encoding.Unicode.GetBytes(text);
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true))
{
await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
};
}
Upvotes: 2