.net - 使用Windows Runtime异步文件API来确保顺序文件访问?

标签 .net multithreading file-io windows-runtime async-await

使用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用作兼容asynclock来同步异步代码:

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/

相关文章:

c# - 如何使用反射复制数组?

c# - 使用 String.IsNullOrEmpty(string) 和 Nhibernate 创建动态 Linq 表达式

.net - 来自 Prometheus .NET 客户端库的 Metrics 实例是线程安全的吗

C++连续读取文件

c# - 如何使用 OnSerializing 和 OnDeserializing 属性?

c# - 我在这里正确使用锁吗?我应该尝试用它包装更少的代码吗?

python - 带子进程的线程

c++ - 如何在大文件上有效地使用文件输入/输出函数(使用有限大小的内存)

android - 如何列出设备上的所有图像?

c# - 环境包括与环境名称属性之间的差异