Using Dispose() ... don't wait until GC kicks in.

G

Guest

Hi,

I'm working on an application where it is essential to free underlying
non-memory resources as soon as they are no longer needed. In my case, it is
a VISA resource which is used in automated tests (involving instruments), but
my question is relevant for any other resource, like those held by a
FileStream. The problem that I'm facing is that this resource is used, either
directly or indirectly, by different objects.

Let me rephrase my problem from a C++ point of view.

In the past (long before something similar showed up in COM) I implemented
smart pointers/handlers (implemented as objects) with automatic ref count
increments and decrements by overloading the copy constructor, assignment
operator, etc. From that moment on I didn't have to worry about freeing
memory too soon or too late. In the case of a resource encapsulated in a C++
object (smart pointer/handle), I didn't have to worry how many times it was
referenced. As soon as it was no longer referenced, the destructor was
invoked and the resource was freed, ready for immediate use by someone else.

Unfortunately (for me) Microsoft decided not to use ref counting in .NET
(e.g. to avoid issues in the case of circular references, which fortunately I
didn't have to deal with) ... so I tried to find a clean method which would
do something similar in C# as I was able to do using C++ (after adding smart
pointers/handles). The only way - to my knowledge - is to use the Dispose()
method in order not to wait for the GC to kick in at an undetermined moment
in the near or far future ... However, at that moment - again to my humble
opinion - there is no way to know that the resource is no longer referenced
(either directly or indirectly). Some C# classes implement bool IsDisposed()
to verify if an object is already disposed or one can catch the
ObjectDisposedException exception. To me however this is not really a clean
solution.

I'm looking forward to learn from clever guys out there to demonstrate that
indeed there is a clean solution to my problem in .NET ...

Thanks for taking the time to read my post and many thanks in advance.
Frans.
 
B

Barry Kelly

Frans wrote:

[IDisposable resource]
The problem that I'm facing is that this resource is used, either
directly or indirectly, by different objects.
I'm looking forward to learn from clever guys out there to demonstrate that
indeed there is a clean solution to my problem in .NET ...

The answer is to either reorganize so there's a single well-defined
owner of the disposable resource, or implement a protocol for disposing
of the resource.

For example, consider implementing an IDisposable handle which disposes
the resource when all outstanding handles have been disposed. That way,
the problem of n-owners of a single resource is reduced to n instances
of 1-ownership, and 1-ownership is well understood through either
'using' or chained disposal via implementing IDisposable and a protected
virtual void Disposing(bool).
Some C# classes implement bool IsDisposed()
to verify if an object is already disposed or one can catch the
ObjectDisposedException exception.

BTW, I think your comments on ObjectDisposedException are a red herring.
It is not an error to dispose an already disposed object, but if you use
a disposed object, you've got a logic error (i.e. you disposed too
early), not a lack of an 'IsDisposed' property.

-- Barry
 
G

Guest

Hey Barry,

first of all thanks for taking a look at my post.

Please correct me if I'm incorrectly interpreting your answer, but aren't
you proposing to implement some kind of reference counting ?

Also another problem that I see is that someone outside the class
(encapsulating the resource) must invoke Dispose(), while in my C++
equivalent, this is automatically dealt with by the destructor of the class
(encapsulating the resource) itself.

With respect to the red herring ;-) ... apparently I was not fully clear ...
what I meant is fully consistent with your feedback (although one typically
prevents that Dispose is invoked more than once): don't use a disposed object.

Thanks.
Frans.
 
S

Scott M.

Don't forget to use the "using" statement when implementing your class, so
it will be automatically disposed when it falls out of scope.
 
G

Guest

Scott M. said:
Don't forget to use the "using" statement when implementing your class, so
it will be automatically disposed when it falls out of scope.

Hey Scott,

I considered this too, but "using" is only a viable solution when the
resource is uniquely used within a small and well-defined portion (the scope
defined by the "using" statement) of the code, no ?

In my case, this is not possible.

Thanks anyway.
Frans.
 
S

Scott M.

Yes, your are correct Frans.


Frans said:
Hey Scott,

I considered this too, but "using" is only a viable solution when the
resource is uniquely used within a small and well-defined portion (the
scope
defined by the "using" statement) of the code, no ?

In my case, this is not possible.

Thanks anyway.
Frans.
 
B

Barry Kelly

Frans said:
Hey Barry,

first of all thanks for taking a look at my post.

Please correct me if I'm incorrectly interpreting your answer, but aren't
you proposing to implement some kind of reference counting ?

That's right. It's rather hard to deterministically dispose of a
resource with multiple owners without counting the number of owners, and
disposing of the resource when the owner count reaches zero. I think an
argument could be made that any deterministic resource disposal
mechanism for resources with multiple owners can be described as
"reference counting".
Also another problem that I see is that someone outside the class
(encapsulating the resource) must invoke Dispose(), while in my C++
equivalent, this is automatically dealt with by the destructor of the class
(encapsulating the resource) itself.

Sure. C# isn't C++. If this is a problem for you, you can use C++/CLI.

:)

-- Barry
 
C

Cor Ligthert [MVP]

Frans,

Are you sure that you can use Net or even more facilities from the windows
operatingsystem. I get the idea that the best thing you can do is strip your
OS down to those services strictly needed.

The time needed to dispose is probably much to long and will interupt your
processes to free your resources and will therefore probably be the horse
behind the cart (and even in the wrong direction).

This was something I was thinking about reading your problem.

Cor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top