Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async lambda and cannot implicitly convert Task.Task.List<Object> to List<Object>

I have the following classes

public PhoneModel
{
    int PhoneID;
    string PhoneType;
    string PhoneNumber;
}
public ContactModel 
{
    int ContactID;
    string FirstName;
    string LastName;
    List<PhoneModel> PhoneNumber;
}

I need to display a list of contacts with all phone numbers of each contacts.

var contactList = await ContactBLL.GetContactList();
IEnumerable<ContactViewModel> contacts = contactList.ToList().ConvertAll(
    async c => new ContactViewModel
    {
        phones = (await ContactBLL.GetContactPhones(c.ContactID)).ToList(),
        firstName = c.FirstName, 
        lastName = c.LastName
    });

I am currently getting the compilation error saying "cannot implicitly convert type 'System.Threading.Tasks.Task.List to IEnumerable...." However, without the async call to get the phone list, it will work (of course without the phones). I can change the async function GetContactPhones() to sync function and it will work as expected. My question is there a way to make the code above work with async call?

Thank you.

like image 662
T L Avatar asked Oct 30 '14 17:10

T L


1 Answers

Currently you're projecting your sequence of items into a collection of tasks that, when completed, can provide your view models. You need to (asynchronously) wait until those tasks all finish if you want to have a sequence of those views. You can use Task.WhenAll to do this:

var contacts = await Task.WhenAll(contactList.Select(
    async c => new ContactViewModel
    {
        phones = (await ContactBLL.GetContactPhones(c.ContactID)).ToList(),
        firstName = c.FirstName, 
        lastName = c.LastName
    }));
like image 69
Servy Avatar answered Oct 28 '22 04:10

Servy