Tip 18 – How to decide on a lifetime for your ObjectContext
One of the most common questions we get is how long should an ObjectContext should live. Options often cited include one per:
This is a classic it depends type of question.
Lots of factors weigh into the decision including:
Cleanly disposing of the ObjectContext and it’s resources is important. It is also significantly easier if you create a new ObjectContext for each Function, because then you can simply write a using block to ensure resources are disposed appropriately:
using (MyContext ctx = new MyContext())
- Cost Of Construction:
Some people are, quite understandably, concerned about the cost of recreating the ObjectContext again and again. The reality is this cost is actually pretty low, because mostly it simply involves copying, by reference, metadata from a global cache into the new ObjectContext. Generally I don’t think this cost is worth worrying about, but as always, there will be exceptions to that rule.
- Memory Usage:
The more you use an ObjectContext, generally the bigger it gets. This is because it holds a reference to all the Entities it has ever known about, essentially whatever you have queried, added or attached. So you should reconsider sharing the same ObjectContext indefinitely. There are some exceptions to that rule and a workaround, but for the most part these approaches just aren’t recommended.
- If your ObjectContext only ever does NoTracking queries then it won’t get bigger because the ObjectContext immediately forgets about these entities.
- You could implement some very explicit tidy-up logic, i.e. implement some sort of Recycle interface, that iterates through the ObjectStateManager detaching entities and AcceptingChanges(..) to discard deleted objects. Note: I’m not recommending this, I’m just saying it should be possible, I have no idea if relative to recreation it will result in any savings. So this might be a good subject for a future blog post.
- Thread Safety:
If you are trying to re-use an ObjectContext you should be aware that is not thread safe, i.e. similar to the standard .NET collection classes. If you access it from many threads (e.g. web requests) you will need to insure that you synchronize access manually.
If your services are designed to be stateless, as most web services should be, re-using an ObjectContext between requests might not be best because, the leftovers in the ObjectContext from the last call may have subtle effects on your application that you are not expecting.
- Natural finite lifetimes:
If you have a natural finite lifetime way of managing an ObjectContext,such as a short lived Form, a UnitOfWork or a Repository, then scoping the ObjectContext accordingly might be the best thing to do.
As you can see there are lots of issues at play.
Most of them tend to point towards a short lived context that isn’t shared.
So that is my recommended rule of thumb.
However as always understanding the reasoning behind a ‘rule of thumb’ will help you know when it is appropriate to go your way.