如何在C#中排队异步文件IO?

时间:2017-08-10 16:03:42

标签: c# asynchronous io

我有一个异步写入日志文件的函数,该函数被多次调用。但是,我收到了错误:

System.IO.IOException: 'The process cannot access the file '<log path>' because it is being used by another process.'

代码在这里:

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();
        }
    });
}

我对异步编程的理解主要来自node.js,它是一种单线程语言。我是否正确地认为,由于C#是多线程的(并且采用多线程方法来处理异步代码),IO不会像在node.js中一样自动排队资源?

有没有一种简单的方法可以在C#中异步写入文件?或者我最好只是使这个日志功能同步,因为性能成本与几行写入无关......

1 个答案:

答案 0 :(得分:2)

Async Void很糟糕,你不能正确捕获异常,也可以通过使用同步方法运行任务来获得Async的全部好处,你仍然会阻止资源。

使用logging framework可能更好,但如果您真的想要,可以像这样编写异步:

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);
    };
}