Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to make async method

Is the following the correct way to make a async method, where the code in the method have to do multiple async calls that needs to be waited on. The plan is to start multiple of this method, and when wait for all of them to finish before the code continues.

    public static Task<string> Get(string url)
    {
        return Task.Run(async () =>
        {
            var client = getBaseHttpClient();
            var result = await client.GetAsync(url).ConfigureAwait(false);
            if (result.IsSuccessStatusCode)
            {
                return await result.Content.ReadAsStringAsync();
            }
            return null;
        });
    }
like image 569
Androme Avatar asked Feb 10 '23 23:02

Androme


1 Answers

Your code:

  1. starts a threadpool thread (Task.Run),
  2. which will start an async I/O operation (GetAsync), and then go back to the threadpool.
  3. When the I/O is done (await), another threadpool thread will be started (ConfigureAwait(false)),
  4. which will start another async I/O operation to read the content of the HTTP response (GetAsStringAsync), and go back to the threadpool.
  5. When the I/O is done (await), another threadpool thread will be started to return the content to the calling method.

You could skip step 1. altogether. All it does is defer the call to getBaseHttpClient to a threadpool thread, which I'll assume is not intensive CPU-bound work - in which case, it could/should be done synchronously.

public static async Task<string> Get(string url)
{
    var client = getBaseHttpClient();
    var result = await client.GetAsync(url).ConfigureAwait(false);
    if (result.IsSuccessStatusCode)
    {
        return await result.Content.ReadAsStringAsync();
    }
    return null;
}

Calling code would be:

var tasks = urls.Select(Get);
var responses = await Task.WhenAll(tasks);
like image 86
dcastro Avatar answered Feb 14 '23 11:02

dcastro