Synchronize you controllers when necessary

Earlier today I happened to lend a hand to a friend of mine that was experiencing a race condition in an ASP.MVC application, like a rag to a bull is multithreading to me.

Here’s the scenario; my friend was calling two web services using methods like BeginXXX/EndXXX. Because her website was IO bound she was correctly using an AsyncController.

She called method to increment the outstanding operations by 2, then proceeded to call

service1.BeginGetValuations(v, ar => {
    AsyncManager.Parameters["valuations"] = service1.EndGetValuations();
    AsyncManager.OutstandingOperations.Decrement();
}, null);
    
service2.BeginGetValuations(v, ar => {
    AsyncManager.Parameters["valuationsActual"] = service2.EndGetValuations();
    AsyncManager.OutstandingOperations.Decrement();
},null);

 

Looked pretty much ok, except once in a while when load tested the valuationsActual parameter was null.
So what could be the cause… Well basically it turned out that there was a race condition accessing the dictionary from two threads.

The solution:

synchronize access to the Parameters, i first thought of doing this with a plain old lock but I was worried about other access on the parameters from the framework itself so I had a quick read of the documentation and turns out that the AsyncManager has a sync method.

 
service1.BeginGetValuations(v, ar => {
    AsyncManager.Sync(() => {
        AsyncManager.Parameters["valuations"] = service1.EndGetValuations();
        AsyncManager.OutstandingOperations.Decrement();
    });
}, null);
    

Do the same for service2.

Comments are closed