'How do I keep my Async method thread safe?
I need to write a method in my Windows Universal App to write to the SD card. How can I ensure two threads do not try to write to the same file at the same time in my method below ?
public async void WriteToCard(string strFileName, IEnumerable<string> listLinesToWrite)
{
IStorageItem item = await folder.GetItemAsync(strFileName);
StorageFile file = (StorageFile)item;
await Windows.Storage.FileIO.WriteLinesAsync(file, listLinesToWrite);
}
Solution 1:[1]
You could keep a map with a ConcurrentDictionary
which maps each file to a SemaphoreSlim
. Then, fetch each semaphore based on the file location you'll be writing to:
private ConcurrentDictionary<string, SemaphoreSlim> fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
public async Task WriteToCardAsync(string strFileName, IEnumerable<string> listLinesToWrite)
{
var semaphoreSlim = fileLocks.GetOrAdd(strFileName, new SemaphoreSlim(1, 1));
await semaphoreSlim.WaitAsync();
try
{
IStorageItem item = await folder.GetItemAsync(strFileName);
StorageFile file = (StorageFile)item;
await Windows.Storage.FileIO.WriteLinesAsync(file, listLinesToWrite);
}
finally
{
semaphoreSlim.Release();
}
}
Side note - Use async Task
instead of async void
. I also added the Async
postfix to the methods.
Solution 2:[2]
You can use the AsyncEx library, which contains an AsyncLock
Assuming there won't be a huge number of filenames, you can use a ConcurrentDictionary
to associate a filename to a lock - otherwise, the dictionary size might grow unbound.
private readonly locks = new ConcurrentDictionary<string, AsyncLock>();
public async void WriteToCard(string strFileName, IEnumerable<string> listLinesToWrite)
{
var lock = locks.GetOrAdd(strFileName, () => new AsyncLock());
using (await lock.LockAsync())
{
IStorageItem item = await folder.GetItemAsync(strFileName);
StorageFile file = (StorageFile)item;
await Windows.Storage.FileIO.WriteLinesAsync(file, listLinesToWrite);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |