[使用实体框架异步执行对Web api的查询存在问题。常规视图,例如,将请求发送到API,并且ActionFilter捕获请求到控制器的功能,使用响应键将其发送到客户端状态为ok,执行请求异步,然后再通过SignalR发送数据。ActionFilter开始异步执行,如下所示:
HostingEnvironment.QueueBackgroundWorkItem(async (ct) =>
{
var response = await actionContext.ActionDescriptor.ExecuteAsync(actionContext.ControllerContext,
actionContext.ActionArguments, ct);
var data = new JavaScriptSerializer().Serialize(response);
await connectionContext.Connection.Send(connectionId, $"{requestKey};{data}");
});
Controller:
[HttpPost]
[Route("")]
public ICollection<TradeAccountModel> GetAll()
{
using (var ls = _lifetimeScope.BeginLifetimeScope())
{
return _tradeAccountService.GetAll();
}
}
服务:
public ICollection<TradeAccountModel> GetAll()
{
using (_tradeAccountRepository.BeginTransaction())
{
return _tradeAccountRepository.Get().Select(acc => acc.ToModel());
}
}
Respository使用UOW模式。并且,当存储库尝试从DB获取数据时,将出现错误:System.InvalidOperationException:由于已处理DbContext,因此无法完成该操作。
如果您的DbContext
注册为范围服务/ HTTP请求范围服务,则应避免将DbContext
从请求管道传递到后台任务。
这是因为根据docs:
安排独立于任何请求的可以在后台运行的任务。
在请求完成后,也将自动实现IDisposable
的所有作用域服务。
您应该在控制器操作中使用独立作用域激活新的DbContext
,并将其传递给后台任务。