我正在使用web api 2和实体框架6.我创建了一个异步web api,它一次更新所有记录。我也使用Autofac进行依赖注入。
我的服务界面如下:
Task<Approval> TakeAction(int id, bool isApprove)
void TakeAction(bool isApprove)
这些是我的服务方法:
public async void TakeAction(bool isApprove)
{
//GetAllDataToApprove is the same function in the service.
var approvalList= GetAllDataToApprove().Approvals.ToList();
foreach (var approval in Approvals)
{
//This is an async method as well
await TakeAction(approval.ApprovalId, isApprove);
}
}
TakeAction方法如下:
public async Task<Approval> TakeAction(int id, bool isApprove)
{
Approval approval= approvalrepository.Query(o => o.ApprovalId == id).FirstOrDefault();
try
{
//updating the approval status
approval.StatusId=5
UpdateDashboard(approval);
approvalrepository.Update(approval);
await unitOfWork.SaveChangesAsync();
}
}
catch (Exception ex)
{
throw ex;
}
return approval;
}
我的网络API方法如下:
[HttpPut]
public IHttpActionResult Put(bool isApprove)
{
try
{
approvalservice.TakeAction(isApprove);
return Ok();
}
catch (Exception ex)
{
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message));
}
}
我想进行非阻塞API调用,这样如果触发此API,它应该批准所有待处理数据。我之所以这样做是异步的原因是因为待处理列表中有很多数据,所以需要很长时间。
我收到以下错误: 无法完成操作,因为DbContext已被处理。
答案 0 :(得分:1)
如果我理解你的问题,可以归结为:
如何从API调用中启动长时间运行的任务,但在完成之前回复。
简答:
您不在 API 中。您委派了服务。
长答案:
您获得的错误很可能归功于Autofac。使用Web Api请求,您可以在请求开始时初始化所需的所有内容,并在最后删除它。在您的代码中,您在请求结束后尝试使用DbContext
执行某些操作并将其丢弃。要解决此问题,只需添加await
,例如await approvalservice.TakeAction(isApprove);
。
执行上述操作意味着您正在等待该过程完成。这不是你想要的。但这是唯一的方法,因为Web Api是以这种方式工作的。
您需要做的是将工作委托给服务。为运行长时间运行的任务而做的事情。一些选项是:
对于您遇到的确切问题,这是一个非常好的阅读。 HowToRunBackgroundTasksInASPNET