在ASP。NET核心Web API项目,我编写了以下接口。第一个请求正常,第二个请求将报告错误。应该是我对异步编程了解不够。我不知道为什么会报告错误。我希望朋友能给我一些建议。
[HttpGet("role_claims")] public async Task<IActionResult> role_claims() { // var user = await userManager.GetUserAsync(User); // var roles = await userManager.GetRolesAsync(user); List<Claim> claims = new List<Claim>(); var roles = this.User.FindAll(ClaimTypes.Role).ToList(); roles.ForEach(async x => { MyRole role = await roleManager.FindByNameAsync(x.Value); IList<Claim> list = await roleManager.GetClaimsAsync(role); Console.WriteLine($"{x.ValueType} {x.Value} {list.Count}"); list.ToList().ForEach(x => claims.Add(x)); }); return Ok(claims.Select(claim => new { claim.Type, claim.Value }).ToArray()); }
错误信息如下
失败:Microsoft。EntityFrameworkCore。查询【10100】 迭代上下文类型“OnePlan”的查询结果时发生异常。Conf.IdentityDb’。 系统ObjectDisposedException:无法访问已释放的上下文实例。此错误的一个常见原因是处理通过依赖项注入解析的上下文实例,然后在应用程序的其他位置尝试使用相同的上下文实例。如果对上下文实例调用“Dispose”,或将其包装到using语句中,则可能会发生这种情况。如果您使用的是依赖项注入,那么应该让依赖项注入容器处理上下文实例。 对象名称:“IdentityDb”。 在微软。EntityFrameworkCore。DbContext。CheckDisposed() 在微软。EntityFrameworkCore。DbContext。get\u DbContextDependencies() 在微软。EntityFrameworkCore。DbContext。微软EntityFrameworkCore。内部的IDbContextDependencies。get\u StateManager() 在微软。EntityFrameworkCore。查询QueryContextDependencies。get\u StateManager() 在微软。EntityFrameworkCore。查询QueryContext。InitializeStateManager(布尔独立) 在微软。EntityFrameworkCore。查询内部的SingleQueryEnumerable 1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken) at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func 4操作,Func 4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable 1.AsyncEnumerator。MoveNextAsync()
失败:Microsoft。EntityFrameworkCore。查询【10100】
迭代上下文类型“OnePlan”的查询结果时发生异常。Conf.IdentityDb’。
系统ObjectDisposedException:无法访问已释放的上下文实例。此错误的一个常见原因是处理通过依赖项注入解析的上下文实例,然后在应用程序的其他位置尝试使用相同的上下文实例。如果对上下文实例调用“Dispose”,或将其包装到using语句中,则可能会发生这种情况。如果您使用的是依赖项注入,那么应该让依赖项注入容器处理上下文实例。
对象名称:“IdentityDb”。
在微软。EntityFrameworkCore。DbContext。CheckDisposed() 在微软。EntityFrameworkCore。DbContext。get\u DbContextDependencies() 在微软。EntityFrameworkCore。DbContext。微软EntityFrameworkCore。内部的IDbContextDependencies。get\u StateManager() 在微软。EntityFrameworkCore。查询QueryContextDependencies。get\u StateManager() 在微软。EntityFrameworkCore。查询QueryContext。InitializeStateManager(布尔独立) 在微软。EntityFrameworkCore。查询内部的SingleQueryEnumerable 1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken) at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func 4操作,Func 4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable 1.AsyncEnumerator。MoveNextAsync()
1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken) at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func
4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable
对于这样几行代码,您会遇到大量令人印象深刻的问题。
从呼叫开始 ToList() 在EF上。核心(可能?)你绝对不应该这样做。异步版本负责工作线程之间的任何多线程同步。
ToList()
那么 ForEach 您使用的函数不支持 async 电话,否则你会等着的。它所做的是不运行任何内容,然后返回 Ok() 结果,然后处理上下文,最后在其中实际运行代码 ForEach公司 ,在处理上下文之后的方式,因此是您的问题。
ForEach
async
Ok()
ForEach公司
要么使用常规 foreach 在实体上,或在 ForEachAsync 分机功能,并在通话中等待。
foreach
ForEachAsync