loading...

.NET How to throttle HttpClient Requests using SemaphoreSlim

rickystam profile image Ricky Stam ・2 min read

Last week I had to deal with an external API that didn't allow for more that 50 requests per second.

On my journey on how to deal with this limitation I stumbled upon SemaphoreSlim Class.

SemaphoreSlim limits the number of threads that can access a resource concurrently. It seemed a good fit and guess what... It was! 😛

I won't bother you with more details, let's see a simplified example on how we can limit our concurrent requests to just 3 per second with code:

class Program
    {
        private static HttpClient httpClient = new HttpClient();

        static async Task Main(string[] args)
        {
            var tasks = new List<Task>();

            // here we set the max allowed concurrent requests, in our case it is 3
            var throttler = new SemaphoreSlim(3);

            // Let's say that we have 12 requests in total that we want to send
            for (var i = 0; i < 12; i++)
            {
                // let's wait here until we can pass from the Semaphore
                await throttler.WaitAsync();

                // add our task logig here
                tasks.Add(Task.Run(async () =>
                {
                    try
                    {
                        var result = await ExecuteRequest();

                        // let's wait here for 1 second to honor the API's rate limit                         
                        await Task.Delay(1000);
                    }
                    finally
                    {
                        // here we release the throttler immediately
                        throttler.Release();
                    }
                }));
            }

            // await for all the tasks to complete
            await Task.WhenAll(tasks.ToArray());
        }

        private static async Task<HttpResponseMessage> ExecuteRequest()
        {
            var result = await httpClient.GetAsync("https://www.bing.com");
            return result;
        }
    }

Please let me know in the comments below what is the equivalent of SemaphoreSlim class in other languages.

You can find the full code on my GitHub

Just run the project and use Fiddler or any other network tool to verify the throttled behaviour.

ALWAYS TRUST BUT VERIFY 😁

This post was written with love ❤️

Posted on Apr 8 by:

rickystam profile

Ricky Stam

@rickystam

Technical Consultant @Microsoft. I love to work with C# and .NET but also enjoy writing JavaScript and Angular. Opinions are my own.

Discussion

markdown guide
 

You are the Greatest American Hero Of All Time!
Short, Sweet, Helpful!

I have been working all day with Parallel.Foreach, and other async stuff, but this is working for me!!!

Thanks again! Pat

 

Thank you sooo much, I'm really happy I could assist! 😄