'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 | 
