下面的代码(在单个DbContext上)导致“在以前的操作完成之前,在此上下文上启动第二个操作”。
[HttpGet]
[Route("api/[controller]/circuit")]
public async Task<IEnumerable<object>> GetAllCircuits()
{
var circuits = await Task.WhenAll((await _context.Circuits.ToListAsync()).Select(async x => new
{
x.Id,
x.FastestLap,
x.LengthInMiles,
Country = await _context.Countries.FirstOrDefaultAsync(c => c.Id == x.CountryId),
Map = await _context.Maps.FirstOrDefaultAsync(m => m.Id == x.MapId),
Locations = await _context.Locations.Where(l => l.CircuitId == x.Id).ToListAsync()
}));
return circuits;
}我可以通过去掉async/await和Task.WhenAll部件,用.Result替换它们,这在.NET中似乎是一个很大的禁忌。
[HttpGet]
[Route("api/[controller]/circuit")]
public async Task<IEnumerable<object>> GetAllCircuits()
{
var circuits = (await _context.Circuits.ToListAsync()).Select(x => new
{
x.Id,
x.FastestLap,
x.LengthInMiles,
Country = _context.Countries.FirstOrDefaultAsync(c => c.Id == x.CountryId).Result,
Map = _context.Maps.FirstOrDefaultAsync(m => m.Id == x.MapId).Result,
Locations = _context.Locations.Where(l => l.CircuitId == x.Id).ToListAsync().Result
});
return circuits;
}我的三个问题是:
.ToList()而不是异步变体吗?谢谢!
发布于 2021-07-31 16:00:24
为什么会发生这种事?
DbContext不允许在同一个db连接上进行多个操作。在本例中,您有一个调用(ToListAsync),然后是多个并发调用( Select)。
的“固定”代码干净吗?如果没有,请你提出一个更好的办法好吗?
不是的。你不应该使用.Result。
你的选择是:
.Result能够工作,但更好的解决方案是使用await,一次只做一次,而不是在Task.WhenAll中使用Select。这种方法的缺点是操作一次只执行一次。。
我可以只使用.ToList()而不是异步变体吗?
ToListAsync不是问题所在。问题是Select + WhenAll。
https://stackoverflow.com/questions/68603561
复制相似问题