Search code examples
c#multithreadingasynchronouswin-universal-appiot

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

  • 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.