异步文件写入问题
本文关键字:问题 文件 异步 | 更新日期: 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提及。
所以看起来我的解决方案是解决问题,但打破多线程的整个想法,我很高兴看到如果有人有更好的解决方案,不会打破多线程。