how to use async/await inside a lambda

2019-05-23 10:20发布

How can I use the async/await keywords correctly in a lambda expression ? here is the code :

public async Task<IHttpActionResult> GetUsers() {

        var query = await _db.Users.ToListAsync();

        var users = query.Select(async u =>  new
        {
            FirstName = u.FirstName,
            LastName = u.LastName,
            IsGeek = await _userManager.IsInRoleAsync(u.Id, "Geek")
        });

        return Ok(users);
}

As you can see this code is running inside a webapi controller, it compiles without any error, the problem is it needs an extra await somewhere because this action never retuns.

Notice that _db and _usermanager are the DbContext and the UserManagerfor the application.

Thanks.

Update :

This equivalent code never fails (but it's not ellegant :( ):

var query = await _db.Users.ToListAsync();
var users = new List<object>();
foreach (var u in query)
{
     bool IsGeek = await _userManager.IsInRoleAsync(u.Id, "IsGeek");
     users.Add( new {
         FirstName = u.FirstName,
         LastName = u.LastName,
         IsGeek= IsGeek
      });
 }
return Ok(users);

1条回答
爷、活的狠高调
2楼-- · 2019-05-23 11:02

Think about your types.

var query = await _db.Users.ToListAsync();

query is a list of users.

var users = query.Select(async u =>  new
{
    FirstName = u.FirstName,
    LastName = u.LastName,
    IsGeek = await _userManager.IsInRoleAsync(u.Id, "Geek")
});

When you Select with an async lambda, the result is a sequence of tasks. So, to (asynchronously) wait for all those tasks to complete, use Task.WhenAll:

var result = await Task.WhenAll(users);
return Ok(result);
查看更多
登录 后发表回答