I’m using a huge binary tree like structure whose nodes may or may not make use of unmanaged resources. Some of these resources may take up a lot of memory, but only a few of them will be in use at a time. The initial state of the tree can be seen as ‘dormant’.
Whenever a node is accessed, that specific node and its children will ‘wake up’ and lazily acquire their assigned resources. Likewise, accesing a different branch in the tree will put the currently active branch to sleep causing its resources to be released. This means that any given node can be woken up and put to sleep once and again at any given time.
I’m currently taking advantage of the IDisposable interface to achieve this. It’s being quite useful because there are a lot of cases where I need to create small branches that will be used locally, and the ‘using’ keyword comes really handy ensuring that no resource will be left open accidentally.
Am I ok implementing IDisposable on objects that don’t really get disposed but sort of put to sleep?
Thanks in advance.
Edit: Thanks all for all the clever answers. I liked the idea of disposing of a resource’s access instead of the resource itself. Now I’m in search of a better name for the function responsible for the clean up. (Any ideas other than Release() or Sleep()? Thanks again.
@Jon Skeet has answered the question really well, but let me chip in with a comment that I feel should be an answer by its own.
It is quite common to use the
usingcode block to temporarily acquire some resource, or enter some form of scoped code you want a clean exit from. I do that all the time, in particular in my business logic controllers, where I have a system that postpones change-events until a block of code has executed, to avoid side-effects multiple times, or before I’m ready for them, etc.In order to make the code look more obvious to the programmer that uses it, you should look at using a temporary value that you
useinstead of the object that has the resource, and returning it from a method name that tells the programmer what it is doing, ie. acquiring some resources temporarily.Let me show an example.
Instead of this:
you do this:
Thus, you’re not actually disposing of anything more than once, since
ResourceScopewill return a new value you dispose of, and the underlying node will be left as is.Here’s an example implementation (unverified, typing from memory):
This allows you to do this:
The fact that I return a struct, and not
IDisposablemeans that you won’t get boxing overhead, instead the public .Dispose method will just be called on exit from theusing-block.