user3825003
user3825003

Reputation: 191

how to update multiple data in entityframework through async web api

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

Answers (1)

hatcyl
hatcyl

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:

  1. HangFire
  2. Azure WebJobs / Cloud Services
  3. Windows Services

This is a really nice read on the exact issue you are having. HowToRunBackgroundTasksInASPNET

Upvotes: 1

Related Questions