Blazor, Httpclient, sync and async WebApi calls

Viewed 408

I'am new to Blazor wasm. Actually I have HttpClient added as singleton to the services in program.cs. Then I use a generic utility class (HttpService) where HttpClient is injected to do http calls (GetAsync, PostAsync,...). Everywhere I use async await pattern. First case: in some page I should do simultaneous get webapi calls and then when all are done do some calculations on results. Second case: in other page I have the opposed need, do a call, wait for result and then use it for a second call.

I try and I notice that my code with calls like:

HttpService:

    public async Task<dataDTO> GetData(int id)
    {
        var httpResponse = await httpService.Get<DataDTO>($"{baseURL}/{id}");

        if (!httpResponse.Success)
        {
            var msg = await httpResponse.GetBody();
            throw new ApplicationException(msg);
        }
        return httpResponse.Response;
    }

And calls in page component:

var result1 = await GetData(5000);
var result2 = await GetData(2000);
var result3 = await GetData(500);

Suppose that the parameter are milliseconds that server use to delay the response. These calls are always syncronous. The next wait the end of previous to be executed. (second case).

How to implement the first case (simultaneous calls)?

Thank you very much.

3 Answers

You can fire them all at once then wait for them to complete using Task.WhenAll.

So your code would be something like this:

//Notice that we don't use await here.
var task1 = GetData(5000);
var task2 = GetData(2000);
var task3 = GetData(500);

Task ResultTask = await Task.WhenAll(new List<Task<dataDTO>> { task1 ,task2, task3 });

 if (ResultTask.Status == TaskStatus.RanToCompletion)
         Console.WriteLine("All tasks completed successfully!");
      else if (ResultTask.Status == TaskStatus.Faulted)
         Console.WriteLine("Operation failed!");  

Also, you can access their result via ResultTask.Result:

foreach (var result in ResultTask.Result) 
{
  //Do stuff
}

You could use Task.WhenAll to allow them to run simultaneously:

dataDTO[] results = await Task.WhenAll(GetData(5000), GetData(2000), GetData(500));

This creates a new Task that completes when all the provided tasks have completed, and amalgamates the results into an array.

var task1 =  GetData(5000);
var task2 =  GetData(2000);
var task3 =  GetData(500);

await Task.WhenAll(task1, task2, task3);

var result1 = task1.Result;
var result2 = task2.Result;
var result3 = task3.Result;

Related