5

I want to be able to run an asynchronous call as follows:

[Route("doit"),ResponseType(typeof(MyModel))]
public IHttpResponse PostAsyncCall(MyModel model){
    //Code removed for simplicity

    Task.Factory.StartNew(() => asyncStuff(model.id);

    return OK(model);
}

private void asyncStuff(int id) {
    MyModel model = db.MyModels.find(id);
    //Do things here. Long call to other webservices/processing of data. Time intensive normally.
    User user = db.Users.find(model.userId);
    //Do more things. Time intensive normally.
}

However, when the async method hits the db. methods an error occurs:

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code

Additional information: The operation cannot be completed because the DbContext has been disposed.

The context used is here:

public class MyContext : DbContext, MyContextInterface
{
        // You can add custom code to this file. Changes will not be overwritten.
        // 
        // If you want Entity Framework to drop and regenerate your database
        // automatically whenever you change your model schema, please use data migrations.
        // For more information refer to the documentation:
        // http://msdn.microsoft.com/en-us/data/jj591621.aspx

        public MyContext() : base("name=MyContext")
        {
        }

        public System.Data.Entity.DbSet<MyAPI.Models.User> Users { get; set; }

        public System.Data.Entity.DbSet<MyAPI.Models.Request> Requests { get; set; }

        public void MarkAsModified(Object item)
        {
            Entry(item).State = EntityState.Modified;
        }

    }

The context is created in the controller as a class variable via:

private MyContextInterface db = new MyContext();

I can see that the db context is being disposed of as the method ends; however, I need to retain this context for the duration of the asynchronous method to access the information needed. How can I do this?

4
  • How is the DbContext being created / disposed? Commented Mar 10, 2015 at 20:08
  • @SLaks It's a db connection through EntityFramework. Commented Mar 10, 2015 at 20:11
  • How is the DbContext instance being created / disposed? Commented Mar 10, 2015 at 20:12
  • @SLaks I have added how the context is created in the controller and the context class. The context is connected to the db via the EntityFramework. Commented Mar 10, 2015 at 20:20

1 Answer 1

6

You start a task but you don't await it, so effectively you immediately call OK. By the time the long running task is finished, indeed your db context is disposed. Just add an await and your problem will be solved.

Sign up to request clarification or add additional context in comments.

7 Comments

I don't want the method to wait until the tasks finishes. I want it to return immediately while the asynchronous task runs in the background, so as to eliminate the user waiting on this long running task.
Then you need to reconsider your design. An alternative is that you really make sure that you context is created when you need it or released when you are really done with it and not earlier. I cannot tell exactly where to do it based on what i have seen in your code so far.
I'm unsure of what direction to take. What further information would be helpful to further clarify the problem?
if you don't need the dbcontext before the find, new it when you do need it and use the using clause. I googled around a bit but cannot find a similar as your problem immediately.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.