异步文件写入问题

时间:2015-07-11 08:47:28

标签: c# .net unit-testing asynchronous async-await

我有下一个测试方法,我正在测试async file write

[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的整个想法。我很高兴看到有人有更好的解决方案,不会打破多线程。

1 个答案:

答案 0 :(得分:0)

谢谢@JonSkeet。我得到了它。我不得不限制访问&#39; WriteTextAsync&#39;方法,这是我的解决方案:

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提到的时间点访问文件。

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