Is tracking tasks in a static dictionary and awaiting tasks initiated in a separate request thread-safe?

248 Views Asked by At

In a .NET Core asp.net web application I'm building, tasks are initiated in a request; in certain scenarios, we want to await the completion of this task in another request.

To accomplish this, I've put in place a static dictionary that stores references to these tasks:

 public static volatile Dictionary<int, Task> MyTasks = new Dictionary<int, Task>();

Running tasks are awaited, if necessary, from separate requests:

 public static async Task GenerateMyData(int itemId, SomeOtherData data)
 {
     var curTask = MyTasks.Get(itemId); //<- extension method wrapper for TryGetValue
     if (curTask != null && !curTask.IsCompleted)
     {
         await curTask;
     }

     var newTask = Task.Run(async () =>
     {
          AddPrimaryData(itemId, data);
          await AddImageData(itemId, data);
          MyTasks[itemId] = null;
     });

     MyTasks[itemId] = newTask;

}

While it works in my development environment and as web-app under a light load, the more I read about async/await the more unsure I am if this will function as expected under a heavier load. Does this method appear to be safe for an asp.net core 2.1 web app?

1

There are 1 best solutions below

1
Olivier Jacot-Descombes On

It's better to use the thread-safe ConcurrentDictionary<TKey,TValue> Class. Making a classic collection volatile alone doesn't make it thread-safe. You would have to enclose all the operations in a lock statement.

You add items with (ConcurrentDictionary<TKey,TValue> Class)

bool success = dict.TryAdd(itemId, data);

And retrieve them with

bool success = dict.TryGetValue(itemId, out data);

There are also methods like TryRemove and TryUpdate.