Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple way to rate limit HttpClient requests

Tags:

c#

async-await

I am using the HTTPClient in System.Net.Http to make requests against an API. The API is limited to 10 requests per second.

My code is roughly like so:

    List<Task> tasks = new List<Task>();
    items..Select(i => tasks.Add(ProcessItem(i));

    try
    {
        await Task.WhenAll(taskList.ToArray());
    }
    catch (Exception ex)
    {
    }

The ProcessItem method does a few things but always calls the API using the following: await SendRequestAsync(..blah). Which looks like:

private async Task<Response> SendRequestAsync(HttpRequestMessage request, CancellationToken token)
{    
    token.ThrowIfCancellationRequested();
    var response = await HttpClient
        .SendAsync(request: request, cancellationToken: token).ConfigureAwait(continueOnCapturedContext: false);

    token.ThrowIfCancellationRequested();
    return await Response.BuildResponse(response);
}

Originally the code worked fine but when I started using Task.WhenAll I started getting 'Rate Limit Exceeded' messages from the API. How can I limit the rate at which requests are made?

Its worth noting that ProcessItem can make between 1-4 API calls depending on the item.

like image 673
Jacob Avatar asked Feb 18 '16 22:02

Jacob


1 Answers

https://github.com/thomhurst/EnumerableAsyncProcessor

I've written a library to help with this sort of logic.

Usage would be:

var responses = await AsyncProcessorBuilder.WithItems(items) // Or Extension Method: items.ToAsyncProcessorBuilder()
        .SelectAsync(item => ProcessItem(item), CancellationToken.None)
        .ProcessInParallel(levelOfParallelism: 10, TimeSpan.FromSeconds(1));
like image 188
TomH Avatar answered Oct 23 '22 21:10

TomH