C# 如何在lambda中使用async/await

C# 如何在lambda中使用async/await,c#,linq,lambda,async-await,asp.net-web-api,C#,Linq,Lambda,Async Await,Asp.net Web Api,如何在lambda表达式中正确使用async/await关键字?代码如下: public async Task<IHttpActionResult> GetUsers() { var query = await _db.Users.ToListAsync(); var users = query.Select(async u => new { FirstName = u.FirstName,

如何在lambda表达式中正确使用async/await关键字?代码如下:

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);
}

想想你的类型

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")
});
使用异步lambda进行选择时,结果是一系列任务。因此,要异步等待所有这些任务完成,请使用Task.WhenAll:


这可能永远不会返回,因为您正在某处同步等待。典型的ASP.NET死锁。也许在用户管理器中?@usr我不这么认为,_usermanager继承自AspNet.Identity usermanager。它需要在某个地方进行额外的等待-你这是什么意思?为什么添加等待会改善情况?至于never returns,不清楚如何调用它,但如果调用方正在等待,则该方法中唯一可以设置卡住的两个位置是对ToListSync的调用和对Ok的调用。这里的第一步是观察调试器中的执行情况,看看它是哪一个,然后精确跟踪代码在那一点上的位置,也就是说,什么调用实际上没有返回等待。好的,那么它可能是正确的。你怎么知道这个动作永远不会回来?当您暂停调试器时,是否有一个线程在某处等待一个有意义的调用堆栈?当您逐步调试调试器时,它挂起在哪里?@usr我正在使用ajax调用和fiddler进行尝试,但两者都没有返回。但为什么请求挂起?内部服务器错误:在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在此上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证线程安全。我仍然认为我们需要在某个地方进行额外的等待。@dafriskymonkey:可能是其他代码导致了该异常。请给出一个最小的、可重复的示例。这是您的答案,您无法并行化此任务,因为您正在访问的基础数据要求您一次只执行一个查询
var users = query.Select(async u =>  new
{
    FirstName = u.FirstName,
    LastName = u.LastName,
    IsGeek = await _userManager.IsInRoleAsync(u.Id, "Geek")
});
var result = await Task.WhenAll(users);
return Ok(result);