使用Windows运行时写入文件时,所有方法都是异步的。在这种情况下是否可以确保我的文件访问和写入顺序进行?
例如,如果我有一个可以从其他多个异步甚至可能是并行代码中调用的日志记录类,那么我如何确保记录器实际同步写入文件?
由于使用async/await,我不能像这样对文件访问进行锁定:
lock (locker)
{
var storageFile = await GetStorageFileAsync();
await FileIO.AppendTextAsync(storageFile, text);
}
我想知道来自Dataflow TPL的BufferBlock是否可以在这种情况下用于序列化编写,但是我不确定究竟该如何设置。我认为它看起来像:
static readonly BufferBlock<string> LogBuffer = new BufferBlock<string>();
public async static Task LogAsync(string message)
{
LogBuffer.Post(message);
string messageToWrite;
while (LogBuffer.TryReceive(out messageToWrite))
{
var storageFile = await GetStorageFileAsync();
await FileIO.AppendTextAsync(storageFile, messageToWrite);
}
}
我可能混合了异步和多线程编程,但是我认为在使用Tasks时,您无法确定将在哪个线程上调用代码。在这种情况下,我想确保一次只能有一个线程可以访问该文件。我朝着正确的方向前进吗?
最佳答案
您想要的是同步异步代码。默认情况下,异步代码是顺序的(如果您对await
执行一项操作,则该方法将在该操作完成之前不会继续执行);您希望它被同步。也不是“同步的”;您仍然希望它是异步的。
您可以只将SemaphoreSlim
用作兼容async
的lock
来同步异步代码:
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
...
await _semaphore.WaitAsync();
try
{
var storageFile = await GetStorageFileAsync();
await FileIO.AppendTextAsync(storageFile, text);
}
finally
{
_semaphore.Release();
}
就是说,如果您希望其余代码在排队写操作后立即继续而不是(异步)等待写操作完成,则可能更喜欢
ActionBlock
。
关于.net - 使用Windows Runtime异步文件API来确保顺序文件访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25265694/