异步文件写入问题

本文关键字:问题 文件 异步 | 更新日期: 2023-09-27 18:02:16

我有下一个测试方法,我正在测试异步文件写入:

[TestMethod]
public async Task TestMethod1()
{
    List<Task> tasks = null;
    int x = 1;
    int step = 10;
    for (int i = step; i <=200; i = i + step)
    {
        tasks = Enumerable.Range(x, step).Select(async y =>
            {
                await TextFile.WriteTextAsync("file.txt", String.Format("{0}'n", y));
            }).ToList();
        x = i + 1;
        await Task.WhenAll(tasks);
    }
}   

异步文件写入代码:

public static async Task WriteTextAsync(string filePath, string text)
{
    byte[] encodedText = Encoding.Unicode.GetBytes(text);
    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Append, FileAccess.Write, FileShare.ReadWrite,
        bufferSize: 4096, useAsync: true))
    {
        await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
    };
}

问题是我的代码生成的文件没有包含所有预期的值。

我期望在文件中看到从1到200的值,但我却有例如

1 
3
5
7
8
12
13
14 
...

查看详细文件在这里http://bit.ly/1JVMAyg也许有人知道发生了什么以及如何解决这个问题?

注意:请参阅我下面的解决方案,即修复丢失项目未插入文件的问题,但它打破了@LasseV提到的多线程的整个想法。Karlsen在评论中说。我很高兴看到如果有人有更好的解决方案,不会打破多线程。

异步文件写入问题

谢谢@JonSkeet。我知道了。我不得不限制访问'WriteTextAsync'方法,这是我的解决方案:

private static SemaphoreSlim _thread= new SemaphoreSlim(1);    
public static async Task WriteTextAsync(string filePath, string text)
{
    byte[] encodedText = Encoding.Unicode.GetBytes(text);
    await _sync.WaitAsync();
    try
    {
        using (FileStream sourceStream = new FileStream(filePath,
            FileMode.Append, FileAccess.Write, FileShare.ReadWrite,
            bufferSize: 4096, useAsync: true))
        {
            await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
        };
    }
    catch(Exception ex)
    {
        Debug.WriteLine(ex.ToString());
    }
    finally
    {
        _thread.Release();
    }
}

注意:这个解决方案修复了未插入文件的遗漏项目的问题,但现在它限制了WriteTextAsync,只有单个线程在@LasseV的时间点访问文件。Karlsen提及。

所以看起来我的解决方案是解决问题,但打破多线程的整个想法,我很高兴看到如果有人有更好的解决方案,不会打破多线程。