Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Metro App FileIO.WriteTextAsync Multiple Threads

I have a method which is called frequently from multiple threads. It involves writing to disk using await FileIO.WriteTextAsync. This works fine when it is called from a single thread, but once I start doing this in multiple threads, I get this error:

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

I know what the error means, but I'm not sure how to work around it. Normally, I would create a lock(object) statement, to ensure that the file is being accessed by only one thread at a time. However, this is an asynchronous method and as such I can't use the await operator in the body of the lock(object) statement.

Please advise on how to handle this scenario.

like image 351
c0D3l0g1c Avatar asked Jun 08 '13 13:06

c0D3l0g1c


1 Answers

You can use SemaphoreSlim to act as an async-compatible lock:

SemaphoreSlim _mutex = new SemaphoreSlim(1);

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

Personally, I don't like the finally, so I usually write my own IDisposable to release the mutex when disposed, and my code can look like this:

async Task MyMethodAsync()
{
  // LockAsync is an extension method returning my custom IDisposable
  using (await _mutex.LockAsync()) 
  {
    ...
  }
}
like image 154
Stephen Cleary Avatar answered Jan 02 '23 11:01

Stephen Cleary