Dispose which doesn't "dispose"

P

Peter

Hi

I have a class which implements IDisposable, but it doesn't really use
the Dispose method for cleaning up resources, it uses it for completing
a calculation.

Actually I think it seems quite smart (I think there are other problems
with the class though) but I was wondering if this was stretching the
use/meaning of IDisposable a bit?

The class is used as part of a module for timing method calls, and you
would use it like:

using (MyTimer timer = new MyTimer("timername"))
{
// Do stuff which needs timing....

} // At the end of the "using", the MyTimer stops its timing


// Get some timing statistics from static method:
double msec = MyTimer.GetMilliseconds("timername");



regards,
Peter
 
J

Jeff Louie

Peter.. It is always a good idea when you try to stretch your mind like
this. I do
wonder if the same functionality can be accomplished with a try finally
block
which may be simpler since there is no need for the timer to implement
IDisposable. So the timer, if valid, would be stopped in the finally
block.

Regards,
Jeff
 
J

Jon Skeet [C# MVP]

Peter said:
I have a class which implements IDisposable, but it doesn't really use
the Dispose method for cleaning up resources, it uses it for completing
a calculation.

Actually I think it seems quite smart (I think there are other problems
with the class though) but I was wondering if this was stretching the
use/meaning of IDisposable a bit?

The class is used as part of a module for timing method calls, and you
would use it like:

using (MyTimer timer = new MyTimer("timername"))
{
// Do stuff which needs timing....

} // At the end of the "using", the MyTimer stops its timing


// Get some timing statistics from static method:
double msec = MyTimer.GetMilliseconds("timername");

It's stretching it, but I've seen similar things before. An alternative
is to use a closure:

timer.Time(() =>
{
// Do stuff which needs timing
});

// Get some timing statistics from static method:
double msec = MyTimer.GetMilliseconds("timername");

(For C# 2 you'd use an anonymous method instead - not much difference
in this case.)
 
P

Peter Morris

using (mocks.Record())
{
}

using (mocks.ReplayAll())
{
}


I think that's how I saw it done anyway :)
 
P

Peter

Jeff said:
Peter.. It is always a good idea when you try to stretch your mind
like this. I do
wonder if the same functionality can be accomplished with a try
finally block
which may be simpler since there is no need for the timer to
implement IDisposable. So the timer, if valid, would be stopped in
the finally block.

In this case, the Dispose method performs some work on internal
variables which cannot be accessed externally. However, one can of
course use a try-catch-finally and call "Dispose" manually.

I think the idea behind using "using" was to ease the use of the class,
and make it "look tidy". The client class does need to ensure it uses
the timer class correctly, but then that sort of "restriction" is
relatively normal.

/Peter
 
J

Jeff Louie

Peter... As you probably know C++ coders like to place initiation code
in the
constructor and do clean up in the destructor for two reasons. First,
C++ has
deterministic destructors so that it will be called when the object goes
out of
scope. Second, the destructor of a fully constructed object will be
called even
if an exception is thrown.

A similar pattern can be applied in C# with IDisposable and using.
However,
unlike C++, the finalizer (destructor) will be called in C# even if an
exception
is thrown in the constructor so you would need to code appropriately.

IMHO, this still begs the question of applying this pattern to stop a
timer as
opposed to:

{
Timer t= new Timer();
t.Start();
...
t.Stop();
}

If the timer must be stopped even if an exception is thrown, then indeed
it
seems to me that:

using (Timer t= new Timer())
{
...
}

is preferable over:

Timer t= new Timer();
try {
t.Start();
...
}
finally {
t.Stop();
}


Regards,
Jeff
variables which cannot be accessed externally. However, one can of
course use a try-catch-finally and call "Dispose" manually.

I think the idea behind using "using" was to ease the use of the class,
and make it "look tidy". The client class does need to ensure it uses
the timer class correctly, but then that sort of "restriction" is
relatively normal.
<<
 

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