1
votes

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
That can work for small number of paralleled requests but Blazor WASM is not really multithread, with a big number of request you gonna loose some. So don't try to send requests in parallels with Blazor WASM. Wait for .Net 6. - agua from mars
Ok thank you. I tried and in this case with 3 request it works fine. - andreat
Sequentialy it works, but if you use Task.WhenAll or Task.WaitAll some request can be lost. - agua from mars

3 Answers

2
votes

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.

2
votes
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;

2
votes

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
}