Reputation: 191
I am using web api 2, and entity framework 6. I have created an async web api, which updates all the records at once. I am also using Autofac for dependency injection.
My service interface is as follows :
Task<Approval> TakeAction(int id, bool isApprove)
void TakeAction(bool isApprove)
These are my service methods :
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 method is as follows :
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;
}
My web-API method is as follows :
[HttpPut]
public IHttpActionResult Put(bool isApprove)
{
try
{
approvalservice.TakeAction(isApprove);
return Ok();
}
catch (Exception ex)
{
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message));
}
}
I want to make a non-blocking API call, such that if this API is triggered, it should approve all the pending data. The reason I made this async is because there are lot of data in the pending list, so it takes a long time.
I am getting the following error: The operation cannot be completed because the DbContext has been disposed.
Upvotes: 0
Views: 869
Reputation: 2352
If I understand your question correctly, it boils down to this:
How do I start a long running task from an API call but respond before it is finished.
Short Answer:
You don't in the API. You delegate to a Service.
Long Answer:
The error you are getting is most likely thanks to Autofac. With a Web Api Request you initialize everything you need at the start of the request and get rid of it at the end. In your code, you are trying to do stuff with DbContext
after your request ended and it got thrown away. To fix this, simply add await
like this await approvalservice.TakeAction(isApprove);
.
Doing the above means you are now waiting for the process to complete. Which is not what you wanted. But this is the only way, because Web Api was made to work this way.
What you need to do instead is delegate the work to a service. Something that was made to run long running tasks. A few options are:
This is a really nice read on the exact issue you are having. HowToRunBackgroundTasksInASPNET
Upvotes: 1