SSA
SSA

Reputation: 5493

Await in async request webapi 2 client

I am trying to understand await an async operation in asp.net MVC web api 2 client (console application). I believe I have done it wrong (due to lack of understanding await and async). It doesn't seem to run async. Here is code to understand the problem

//Main function

static void Main()
{
    RunAsync().Wait();

}

//RunAsync

static async Task RunAsync()
{
    using (var client = new HttpClient())
    {
        var apiUrl = ConfigurationManager.AppSettings["apiurl"];
        client.BaseAddress = new Uri(apiUrl);

        ....some code to fetch data

        foreach (var updateObject in updatedata)
        {
            HttpResponse  response = await client.PostAsJsonAsync("webapimethod", updateObject);
            if (response.IsSuccessStatusCode)
            {
                JArray content = await response.Content.ReadAsAsync<JArray>();
            }
        }
    }
}

In the above code, foreach loop I am making request in loop as PostAsJsonAsync call and then I use ReadAsAsync to get response back but request always runs sync. not like fired and then when response arrives read the data.

It works fine but I want it to be async and not waiting on each request. How to achieve that or please explain await async in this context? Trying to read blogs and articles but I don't get how it will work.

Upvotes: 3

Views: 2151

Answers (2)

Alexander Derck
Alexander Derck

Reputation: 14488

The syntax you're probably looking for is this:

public async Task<JArray> GetContentAsync(... updateObject)
{
  HttpResponse  response = await client.PostAsJsonAsync("webapimethod", updateObject);
  if (response.IsSuccessStatusCode)
  {
      return await response.Content.ReadAsAsync<JArray>();
  }
}

Here your thread from the GetContentAsync() method will be put back on the threadpool while the client.PostAsJsonAsync is happening due to the await keyword.

Then you can create all the tasks in your method which calls it:

var updateData = fetchData();
var tasks = updateData.Select(d => GetContentAsync(d));
var result = (await Task.WhenAll(tasks)).ToList();

The Select will create a task for each of your result. The await Task.WhenAll will unwrap the Task<JArray> and create a List<JArray>

Upvotes: 3

Carlos Delgado
Carlos Delgado

Reputation: 336

You have to move foreach out of RunAsync method. To get RunAsync in a foreach loop to work in async mode, you have to create several tasks and then call Task.WaitAll

Upvotes: 1

Related Questions