Wesley
Wesley

Reputation: 5621

Trouble with AWAIT / ASYNC and WebApi with FOREACH

I have multiple async methods that return the same type from different OAuth based REST Api calls.

If I call one directly, I can get the data back:

//Call a specific provider
public async Task<List<Contacts>> Get()
{
    return await Providers.SpecificProvider.GetContacts();
}

However, if I try to loop through multiple accounts, the object is returning before the AWAIT finishes:

//Call all providers
public async Task<List<Contacts>> Get()
{
    return await Providers.GetContactsFromAllProviders();
}

public async Task<List<Contacts>> GetContactsFromAllProviders()
{
    var returnList = new List<Contacts>();
    //Providers inherits from List<>, so it can be enumerated to trigger
    //all objects in the collection
    foreach (var provider in Providers)
    {
        var con = await provider.GetContacts();
        returnList.Add(con);
    }
    return returnList;
}

I'm new to async and am probably missing something simple

Upvotes: 0

Views: 1153

Answers (1)

Martin Liversage
Martin Liversage

Reputation: 106796

The code you have provided will call the web service for each provider one by one in a serial fashion. I do not see how your statement the object is returning before the AWAIT finishes can be true because inside the loop the call to GetContacts is awaited.

However, instead of calling the providers serially you can call them in parallel which in most cases should decrease the execution time:

var tasks = providers.Select(provider => provider.GetContacts());

// Tasks execute in parallel - wait for them all to complete.
var result = await Task.WhenAll(tasks);

// Combine the returned lists into a single list.
var returnList = result.SelectMany(contacts => contacts).ToList();

Upvotes: 5

Related Questions