How to handle batch processing of multiple requests using Task in ASP.NET?

I have a list of selected content IDs, and for each content ID, I need to call the api, get the response and then store the resulting response for each content in the DB.

At that time, the user can select any amount of content in the range 1 to 1000 and can pass that to update the content db data after receiving a response from the api.

In this situation, I create multiple requests for each content.

I was thinking of continuing with asp.net async Task and wrote the following method.

The code I have currently written creates one task for each contentId and I am currently waiting on the entire task to get a response.

Task.WaitAll (All tasks);

public static Task<KeyValuePair<int, string>> GetXXXApiResponse(string url, int contentId)
{
    var client = new HttpClient();

    return client.GetAsync(url).ContinueWith(task =>
    {
        var response = task.Result;
        var strTask = response.Content.ReadAsStringAsync();
        strTask.Wait();
        var strResponse = strTask.Result;

        return new KeyValuePair<int, string>(contentId, strResponse);
    });
}

      

Now I think about every task I create, it will create one thread and in turn with a limited number of worker threads, this approach will end up taking all the threads, which I don't want.

Can anyone help me / me help to deal with this situation efficiently by handling multiple api requests or some kind of batch processing using asynchronous tasks, etc.?

FYI: I am using .NET framework 4.5

+3


source to share


1 answer


A task is simply a representation of an asynchronous operation that can be waited and canceled. Creating new tasks does not necessarily create new threads (it generally does not). If you use it async-await

correctly, you don't even have a thread during the larger asynchronous operation.

But making multiple requests concurrently can be problematic (for example, burdening the content server too much). Thus, you can still limit the number of concurrent calls with SemaphoreSlim

or TPL Dataflow

:

private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(100);

public static async Task<KeyValuePair<int, string>> GetXXXApiResponse(string url, int contentId)
{
    await _semaphore.WaitAsync();
    try
    {
        var client = new HttpClient();
        var response = await client.GetAsync(url);
        var strResponse = await response.Content.ReadAsStringAsync();
        return new KeyValuePair<int, string>(contentId, strResponse);
    }
    finally
    {
        _semaphore.Release();
    }
}

      



To wait for these tasks to complete, you should use Task.WhenAll

await asynchronously instead Task.WaitAll

, which blocks the calling thread:

await Task.WhenAll(apiResponses);

      

+6


source







All Articles