Search code examples
c#asynchronous.net-coreasync-awaitsemaphore

.Net Core Async critical section if working on same entity


I need to be sure that a method accessed via a web API cannot be accessed by multiple call at the same time if it work on the same object with the same id

I understand the use of SemaphoreSlim but a simple implemetation of that will lock the critical section for all. But I need that section locked only if it works on the same entity and not on 2 different

This is my scenario, an user start to work, the entity is created and is ready to be modified, then one or more user can manipulate this entity, but a part of this manipulation has to be in a critical section or it will lead to inconsistent data, when the work is finished, the entity will be removed from the work status and moved to and archive and can only be accessed readonly

The class which contains that function is injected as transient in the startup of the application

 services.AddTransient<IWorkerService>(f => new WorkerService(connectionString));
public async Task<int> DoStuff(int entityId)
{
  //Not Critical Stuff

  //Critical Stuff

  ReadObjectFromRedis();
  ManipulateObject();
  UpdateSqlDatabase();
  SaveObjectToRedis();

 //Not Critical Stuff
}

How can I achieve that?


Solution

  • Try this, I'm not sure if those objects are available in .net-core

    class Controller
    {
        private static ConcurrentDictionary<int, SemaphoreSlim> semaphores = new ConcurrentDictionary<int, SemaphoreSlim>();
    
        public async Task<int> DoStuff(int entityId)
        {
            SemaphoreSlim sem = semaphores.GetOrAdd(entityId, ent => new SemaphoreSlim(0, 1));
            await sem.WaitAsync();
            try
            {
                //do real stuff
            }
            finally
            {
                sem.Release();
            }
        }
    }