Destroying objects, the IDisposable interface and memory management

A

Andrew Falanga

Hi,

How can I force an objects destructor to execute? I'm writing a WCF
server and client. The server makes a dictionary of objects that are
operated on at the request of the client. I wrote it to be a
dictionary because I saw that the dictionary had a remove method to
remove objects from the dictionary. Now I thought that removing the
object would make it so that there was no more valid reference to the
object and thus garbage collection would come along and dispose of
it. This isn't happening though. I remove all elements in my
dictionary and the objects desctructors are not called. The one way I
know this is that each object makes a temporary file for processing
data and should delete this temp file when the destructor is called.
However, these temp files hang out until the WCF server reaches the
obj.Close() method call.

So, how does one force a call to a destructor?

Andy
 
G

gareth erskine-jones

Hi,

How can I force an objects destructor to execute? I'm writing a WCF
server and client. The server makes a dictionary of objects that are
operated on at the request of the client. I wrote it to be a
dictionary because I saw that the dictionary had a remove method to
remove objects from the dictionary. Now I thought that removing the
object would make it so that there was no more valid reference to the
object and thus garbage collection would come along and dispose of
it. This isn't happening though. I remove all elements in my
dictionary and the objects desctructors are not called. The one way I
know this is that each object makes a temporary file for processing
data and should delete this temp file when the destructor is called.
However, these temp files hang out until the WCF server reaches the
obj.Close() method call.

So, how does one force a call to a destructor?

You can force garbage collection, with:

GC.Collect()

but that's rarely needed (or a good idea).

Normally you'd implement the IDisposable interface, and release your
unmanged resources in the Dispose method. You'd then call
Dispose(true) on each of your objects after removing them from the
dictionary.

GSEJ
 
A

Andrew Falanga

You can't.  At best, you can have the finalizer (the "more correct" term  
for that special method) call a method that you can call explicitly when  
you want the same work to be done explicitly.

I didn't think so, but wanted to know if there's a way to do it.
The List<T> class also has a Remove() method.  So does ArrayList.  And any  
number of other collection classes.

Dictionary<TKey, TValue> might be the right class to use, or it might  
not.  But the presence of a Remove() method isn't what determines that.

That wasn't the reason. I started with a List<> object but discarded
it because removing items from the list reordered the list and broke
my indexing methods. The Dictionary said:
Now I thought that removing the
object would make it so that there was no more valid reference to the
object and thus garbage collection would come along and dispose of
it.  This isn't happening though. [...]

That's right.  Assuming the object truly is unreachable, finalization and  
collection of the object might happen right away.  It might happen later.  
It might not happen at all.  Your code should not depend on garbage  
collection behavior, including execution of the finalizer.  Instead,  
implement IDisposable in objects that have unmanaged resources in need of 
cleaning up, and make sure to call the Dispose() method when you are done 
with the object.

Note that part of your issue may be that the dictionary instance isn't the  
only place the objects are referenced.  Your statement implying that the  
finalizer eventually does get called after some "obj.Close()" method is  
called (though you don't bother to tell us what "obj" is) suggests that  
the objects you expected to get finalized and collected are still being  
referenced somewhere else, until that Close() method is called.

I thought that mentioning I was making a WCF service it would be clear
that the obj.Close() call is the object of type WCFServer. Sorry that
it wasn't as clear as I intended.


Without a concise-but-complete code example that reliably demonstrates the  
issue, it's impossible to provide specific advice.  In the meantime,  
hopefully the above helps explain the basics.

Basically, what I have is this:

using System.Collections.Generic;
using some.class.library; // this library does image comparisons
using both managed and unmanaged code

class WCFServer {
int index = 0;
Dictionary<int, ComparisonClass> graphics;

int GetImgReference(string path) {
graphics.Add(++index, ComparisonClass(path));

return index;
}

bool RemoveImgReference(int index) {
return graphics.Remove(index);
}
}

class ServerProgram {
void public static Main() {
WCFServer myServ = new WCFServer();

myServ.Open();

Console.WriteLine("server started, press <enter> to exit");

Console.ReadLine(); // wait

WCFServer.Close();
}
}


Bear in mind that I'm just developing things now. Then, on the WCF
client side, the client makes a new class that calls to the server
using these functions. So the server starts, opens the sockets and
waits for clients to connect. The client calls the MakeImgReference
(path) function and obtains an index into the dictionary for the
objects stored there. Then, using the RemoveImgReference(index)
function, deletes objects from the dictionary. My plan was that by
removing the element from the dictionary whatever resources used by
that object would be freed and garbage collection would take place.
However, this isn't happening.

Thanks,
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