Recently one of our clients had an issue with concurrent Web API calls. Each web api call was making a call to COM DLL using interops, due to the concurrent request made to the endpoint the COM dll method was out of order and was processing incorrectly by mixing the request with another request json body.
Initially we thought it could be the issue with COM objects not disposed properly, so we started investigating around that area, but still the problem persisted.Later with lot’s of logs we found the issue was with accepting concurrent request made to the endpoint.
Solution1 : Started of looking at locking object which locks a given delegate function and waits till it has finished the task and accepts the next request.
public class Throttle
private static object lockMethod= newobject();
public static IEnumerable<string> LockRequest(Func<IEnumerable<string>> action)
This solved the issue, where it throttled all the incoming request from IIS and making it synchronous. But didn’t support existing async await methods.
Solution 2: Using SemaphoreSlim
SemaphoreSlim is meant for throttling thread\request and is configurable too, also it allow us to keep all the existing task async wait in delegate methods and no changes are required for the existing methods which has async await.
static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1);
public static async Task<IEnumerable<string>> LockRequest(Func<Task<IEnumerable<string>>> action)
return await action();
WaitAsync waits on the each thread to complete task, and gets stacked up all the request here.
This solved the issue with throttling, where we throttled to one concurrent thread based on requirement.
But this might cause another issue as the task timeout increases the IIS connection timeout increased too and IIS would open up more threads and might get into starving thread. As long the task we are performing is not time consuming it should be fine, also by increasing request timeout on the client request HTTPClient timeout issue can be solved.
You don’t have to throttle to one thread, but in your use case you could throttle to any numbers of request/
This is a good way you can control the request coming to your site and blocking other request as IIS can warm up and run out of threads. Most of the companies with high volume of hits on websites would have this mechanism of throttling.