0

I am using c# .net

I have a POST method in my controller that gets called very quickly by a client. This method gets run concurrently by MVC nature.

[HttpPost]
public IActionResult PostDog(){
    AddDog(TempData, new Dog());
    return Json("success");
}

That method calls another method that need to have a critical section.

public bool AddDog(ITempDataDictionary tempData, dog){
    /* critical section */
    List<Dog> dogs = (List<Dog>)(tempData["myDogList"];
    dogs.Add(dog);
    tempData["myDogList"] = dogs;
    /* end critical section */
    return true;
}

If the critical section is run parallel, it will will result is lost data.

Is there a way I can implement a critical section using this MVC structure?

*edit - to clarify why the Post Method can be run concurrently:

The method PostDog Can be run concurrently because if a client submits a form or something multiple times very quickly (eg. 10x per second), then the Server will process those Post requests as they come in parallel, instead of making the last request wait to start until all the previous ones are completed.

*edit 2

It looks like using a lock solved my concurrency Issues, but it seems like TempData is not getting updated. Perhaps it has to do with how TempData gets passed to AddDog...

private static readonly object TempDataLock = new();

public static bool AddDog(ITempDataDictionary tempData, dog){
    lock(TempDataLock )
    {
        /* critical section */
        List<Dog> dogs = (List<Dog>)(tempData["myDogList"];
        dogs.Add(dog);
        tempData["myDogList"] = dogs;
        /* end critical section */
    }
    return true;
}
Uuuuuumm
  • 608
  • 5
  • 21
  • 2
    *This method is not marked as async, but it gets run asyncronously by MVC nature* Maybe I'm being dense today but I have no idea what this means. – John Wu Jun 07 '23 at 16:16
  • 1
    *"it gets run asyncronously by MVC nature"* - No, it gets run *in parallel* with other requests. "Async" applies to each action individually, and only if the action method is marked `async`. Parallel (multi-threaded) execution is the real issue here. A critical section cannot run asynchronously, and this is formalized by the fact that the `lock` statement cannot be used in methods marked `async`. These methods are not marked `async` so you can use `lock` just fine. If another method, marked `async`, needs to guard the same data, that portion needs to be extracted to a non-async method. – madreflection Jun 07 '23 at 16:24
  • *"If the critical section is run parallel"* - If it's a critical section, it can't be run by two threads at the same time. You don't have a critical section yet, only a candidate block for a critical section. – madreflection Jun 07 '23 at 16:31
  • 1
    @madreflection the term *in parallel* is not accurate either. The correct term is *concurrently*. See [this](https://stackoverflow.com/questions/4844637/what-is-the-difference-between-concurrency-parallelism-and-asynchronous-methods "What is the difference between concurrency, parallelism and asynchronous methods?") question for details. – Theodor Zoulias Jun 07 '23 at 16:32
  • @madreflection Correct, I suppose I am asking how I can make that block a critical section. – Uuuuuumm Jun 07 '23 at 16:32
  • 1
    @TheodorZoulias: Apologies. Yes. Brain fart. – madreflection Jun 07 '23 at 16:33
  • @Uuuuuumm: The `lock` statement is how you do critical sections idiomatically in C#. – madreflection Jun 07 '23 at 16:34
  • 2
    OP, what are you trying to accomplish overall? I suspect there are serious problems with your thinking. The ASP.NET synchronization context eliminates the need for most locks. And it makes very little sense to lock on an instance of `TempData` (the instance is not likely to be reused for other requests) or to keep a list in there (as TempData items are deleted after they are used). – John Wu Jun 07 '23 at 17:07
  • @JohnWu The list of Dogs, is actually a list of objects that will be turned into bootstrap toasts for error messages or success messages. Since multiple errors may be thrown I change my using TempData to store 1 toast to using TempData to store a list of toasts – Uuuuuumm Jun 07 '23 at 17:47

0 Answers0