Metro App FileIO.WriteTextAsync Несколько потоков

У меня есть метод, который часто вызывается из нескольких потоков. Это включает запись на диск с использованием await FileIO.WriteTextAsync, Это прекрасно работает, когда он вызывается из одного потока, но как только я начинаю делать это в нескольких потоках, я получаю эту ошибку:

The process cannot access the file because it is being used by another process.

Я знаю, что означает ошибка, но я не уверен, как обойти ее. Обычно я бы создал lock(object) оператор, чтобы гарантировать, что файл доступен только одному потоку за раз. Тем не менее, это асинхронный метод, и поэтому я не могу использовать await оператор в теле lock(object) заявление.

Посоветуйте, пожалуйста, как справиться с этим сценарием.

1 ответ

Решение

Ты можешь использовать SemaphoreSlim действовать как async-совместимый замок:

SemaphoreSlim _mutex = new SemaphoreSlim(1);

async Task MyMethodAsync()
{
  await _mutex.WaitAsync();
  try
  {
    ...
  }
  finally
  {
    _mutex.Release();
  }
}

Лично мне не нравится finallyпоэтому я обычно пишу свой IDisposable чтобы освободить мьютекс после его удаления, и мой код может выглядеть так:

async Task MyMethodAsync()
{
  // LockAsync is an extension method returning my custom IDisposable
  using (await _mutex.LockAsync()) 
  {
    ...
  }
}
Другие вопросы по тегам