optimizing parallel webservice calls

Posted on

Problem

In my project I have an async method AnAsynWebServiceCallHere for calling a web service. I want to call AnAsynWebServiceCallHere twice in parallel and at the end I want to return the combined result. Will at the end of this method

public async Task<List<DesiredResult>> GetMyDesiredData(MyParamDTO dto)
{
  List<DesiredResult> list = new List<DesiredResult>();
  await Task.WhenAll(
    Task.Run(()=> {var result1 = AnAsynWebServiceCallHere(dto.A);list.Add(result1);}), 
    Task.Run(()=> {var result2 = AnAsynWebServiceCallHere(dto.A);list.Add(result2);})
  );
  return list;
}

and body of the ” method is:

public async Task<DesiredResult> AnAsynWebServiceCallHere(string sqlQuery)
{
  string json;
  using(HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://demoapi.MyHost.net/SQLRunner"))
  {
      request.Headers.Add("id", SECURITY_TOKEN);          
      request.Headers.Add("sqlStatement", sqlQuery);
      HttpResponseMessage response = await client.SendAsync(request);
      json = await response.Content.ReadAsStringAsync();
  }
  return JsonConvert.DeserializeObject<DesiredResult>(json);
}

Is the written method an elegant approach?

Update:
Context provided with the called method body.

Solution

If AnAsynWebServiceCallHere is already async then there is no need for the additional Task.Run in the Task.WhenAll.

Task.WhenAll<TResult>(param Task<TResult>[]) will already return the results of the tasks in the collection as an array of results.

All that is left then is to convert the array to a List<>

public async Task<List<DesiredResult>> GetMyDesiredData(MyParamDTO dto) {
    var results = await Task.WhenAll(
        AnAsynWebServiceCallHere(dto.A), 
        AnAsynWebServiceCallHere(dto.A)
    );
    return results.ToList();
}

All the tasks will run in parallel and at the end will return the combined results.

Looking at the AnAsynWebServiceCallHere you could also wrap the response in a using statement as it is disposable also

public async Task<DesiredResult> AnAsynWebServiceCallHere(string sqlQuery) {
    var url = "https://demoapi.MyHost.net/SQLRunner";
    using(var request = new HttpRequestMessage(HttpMethod.Post, url)) {
        request.Headers.Add("id", SECURITY_TOKEN);          
        request.Headers.Add("sqlStatement", sqlQuery);
        using(HttpResponseMessage response = await client.SendAsync(request)) {
            var json = await response.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<DesiredResult>(json);
        }
    }      
}

Leave a Reply

Your email address will not be published. Required fields are marked *