简体   繁体   中英

disposing object context on application_endrequest

I'm facing an issue with the EF4 object context which I store inside HttpContext.Current.Items , and then want to dispose as soon as the request is handled fully.

On Aplication_EndRequest event I call the Terminate() method of the RepositoryContext, which would find the active ObjectContext from the HttpContext.Current.Items collection, and call Close() on its connection and Dispose() on it.

The problem is that sometimes I get weird behavior on one of my pages. On some occasions I get an error saying:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

I thought that maybe this might happen since not only page requests call the Application_EndRequest event once they finish but also image requests and etc', and hence maybe sometimes other requests disposes the main page request ObjectContext before it is finished doing its job, but that should not happen since everything is made on the collection HttpContext.Current.Items which is of course not shared between HTTP requests.

Also, from research maybe it is caused due to lazy loading of some db requests, but this should not be the case here because I do not call Dispose anywhere else on code (I've checked) and hence Dispose() on the EndRequest should be called only when everything is finished, shouldn't it?

Any ideas on what might cause this? How can I test it? what would you suggest?

Thanks!

This means that Dispose() was already called on the ObjectContext. There are many different reasons as to why this is happening, but it boils down to the fact that something is calling Dispose() before Application_EndRequest. Without all of the source it would be impossible to tell exactly why.

Because you are asking for recommendations, my first would be to take the ObjectContext out of HttpContext. The database connection should only live for a short time, and execute a specific task. If it is short lived you can put the ObjectContext inside of a using statement which will automatically call Dispose() for you.

Supposing you have a class that provides you the current ObjectContext, it's possible a programmer, following some examples from a blog or something like that, had written this:

using(var context = ContextProvider.GetCurrentContext()){
    ...
}

and disposed the ObjectContext before the request ends.

If you want to test where the ObjectContext is being disposed, you can do this:

In your ObjectContext implementation, change the Dispose method to:

public override void Dispose() {
    throw new InvalidOpearationException("Gotcha!");
}

public void ActuallyDisposePlease() {
    base.Dispose();
}

And in the Application_EndRequest call the ActuallyDisposePlease() method.

OF COURSE, this is for testing/debugging/diagnosis perspective and NEVER should hit production.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM