Managing/Disposing Memory in local scopes

A

AAJ

Hi

I have written a wrapper that encapsulates the Excel object model. As anyone
who's done a similar thing knows, its important to release the objects when
the app exits otherwise they still remain as a running process within
windows.

I've done this and so long as the code is called, it works well.

I then implemented Idisposable, and in my class put the clean up code in the
Dispose method.

Again this works OK so long as I call the dispose method when I'm done.

What I wanted, and what I thought would happen is that when the object went
out scope, it would be disposed of.

i.e.

private void button1_Click(object sender, EventArgs e)
{
ExcelWrapper TestSheet = new ExcelWrapper(@"C:\Test.XLS");
....
....
}

Dispose called here???


I thought the dispose method would have been called automatically as it
exited the function.

So what I'm getting at is, is there any way of ensuring that objects are
cleared automatically when they leave scope, or is it the programmers
responsibility.

thanks in advance

Andy
 
L

Laura T.

Dispose is user level pattern, not a system pattern.
GC calls only finalizers. It does not care about anything else (or almost).
You must create a finalizer (aka C++ destructor) for your object, ~<your
object> where you clean up the unmanaged resources. You should, quite a
must, disable your finalizer if someone calls dispose.
Look more on the documentation regarding dispose and finalizer pattern.

Laura
 
S

Stoitcho Goutsev \(100\)

AAJ
make you object to implement IDisposable if you didn't do so already. Then
in your method you can use the c# using statement

private void button1_Click(object sender, EventArgs e)
{
using(ExcelWrapper TestSheet = new ExcelWrapper(@"C:\Test.XLS"))
{
......
.....
}
}

TestSheet sheet object is going to be disposed as soon as it exits the using
statement scope. the using statement is compiled as try/finally block so of
you prefer you can write it that way.
 
H

Helge Jensen

AAJ said:
private void button1_Click(object sender, EventArgs e)
{
ExcelWrapper TestSheet = new ExcelWrapper(@"C:\Test.XLS");
...
...
}

Dispose called here???

I thought the dispose method would have been called automatically as it
exited the function.

As others suggested, use "using".
So what I'm getting at is, is there any way of ensuring that objects are
cleared automatically when they leave scope, or is it the programmers
responsibility.

I use the following pattern to verify that Dispose was not forgotten:

public class Foo: IDisposable {
// stuff
public void Dispose() {
GC.SuppressFinalize(this);
}
~Foo() {
// Someone forgot dispose
try {
// Remember, that referenced objects may have been GC'ed already
// so the code may throw, but it's worth a try

// you can try logging instead, or whatever you wish to do
string msg = string.Format("{0}: Missing dispose", this);
throw new InvalidOperationException(msg);
} finally {
// Dispose anyway, may fail in destructor -- but worth a try
Dispose();
}
}
}

When a forgotten Dispose is spotted, by looking at logs or catched in
the debugger, I mixin a "CallStackOnConstruction" member on the class:

public class Foo: IDisposable {
...
string trace = CallStackOnConstruction.AsString();
}

and refine ~Foo to show that call-stack.

This pattern works *really* well for debugging forgotten Dispose,
atleast for me :)
 
A

AAJ

Many thanks for the quick responses. I never thought to try 'Using',
completely slipped my mind!!!

I'll have a look at finalisers as well, its something new to me, and its
always good to learn.

thanks again

Andy
 

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