Singleton VS Finalize

G

Guest

Hi,
i created a singleton. This singleton read a config file in the constructor
and write it in the finalize. I got a big problèm, the finalize it's not
always call!! :( I don't know what do that it is call or not.. it's seem
random ! It's supose to call it when the application terminate.

I use the 4th pattern from this page :
http://www.yoda.arachsys.com/csharp/singleton.html

My singleton is in a dll.. It have only 1 other class (in another dll) who
use my singleton... And this class assign 0 to pointer when it not more need
the singleton.
I tried to add a "GC::Collect()" just before my app terminate.. no changes..
They are some problem with the singleton / garbage collector / finalize ?!

Here is my code (simplified):

public __sealed __gc class Singleton
{
public:
static Singleton* GetSingleton(){return m_Singleton;}

ObjectItem GetItem(String* _Module, String* _Name, Object*
_defaultValue);
Void SetItem(String* _Module, String* _Name, Object * _value);

//A try...
~Singleton();

private:
static Singleton(){};
//I tried with only the static constructor.. no changes..
Singleton();

//File management
Void WriteFile();
Void ReadFile();

///<summary>
/// The singleton
///</summary>
static Singleton* m_Singleton = new Singleton();
};
 
S

Sylvain Lafontaine

No more finalize clauses are called when an application finish. The
finalize function will be called only if the application continue for a
minimum of time after the object has been collected; in case the resources
previously taken by the object are needed again. When the application
finish, obviously there will be no more need for these resources, so there
is no need to call any finalize clause. This point is clearly indicated in
the documentation of the GC.

Calling the GC::Collect() just before the termination of your application
won't change nothing to that. You can change this policy by calling the
function System.GC type's RequestFinalizeOnShutdown; however this is not a
recommended practice. If you really need something to be called when your
application finish, then the design of your application should take care of
that explicitely.

S. L.
 
J

Jon Skeet [C# MVP]

Christian said:
i created a singleton. This singleton read a config file in the constructor
and write it in the finalize. I got a big probl?m, the finalize it's not
always call!! :( I don't know what do that it is call or not.. it's seem
random ! It's supose to call it when the application terminate.

Instead of using a finalizer, try using one of the AppDomain events
such as DomainUnload.
 
D

David Levine

Sylvain Lafontaine said:
No more finalize clauses are called when an application finish. The
finalize function will be called only if the application continue for a
minimum of time after the object has been collected; in case the resources
previously taken by the object are needed again. When the application
finish, obviously there will be no more need for these resources, so there
is no need to call any finalize clause. This point is clearly indicated
in the documentation of the GC.

All the current documentation and information on this subject that I've seen
indicates exactly the opposite. I found an old Richter article (circa 2000)
that talked about this, but more recent information contradicts him; I
suspect that the runtime has changed its behavior, especially because there
currently is no exposed type called GC.RequestFinalizeOnShutdown.

One of the primary uses of a finalizer is to cleanup unmanaged resources
that the managed object has a reference to...not calling a finalizer can
have catastrophic effects, so they need to get called even at system
shutdown.

Chris Brumme blogged about this topic and so long as the runtime is shutting
down cleanly the finalizer will always get called, even if the object is
still reachable. There are cases where a finalizer may not get called but
all those cases arise from catstrophic,unrecoverable circumstances and/or
the process has terminated in an unclean manner. AFAIK the only reason why a
finalizer will not get called is when GC.SuppressFinalize is invoked on an
object. If a finalizer throws an exception the runtime swallows it and
continues to call other finalizers - only the faulted finalizer will not run
to completion.

However, there is another (real) reason for not writing to the file in a
finalizer, especially at system shutdown.

This has to do with the fact that there is no guaranteed order that
finalizers are invoked in, and at system shutdown it is possible for various
parts of the managed runtime to have already been shutdown when your
object's finalizer gets called. It is more likely that the some part or all
of the runtime's file system has already been shutdown and it is invalid to
be invoking it from within the finalizer.

Instead, the OP should subscribe to the AppDomain.ProcessExit event (not the
AppDomain.DomainUnload) and write to the file from there. The DomainUnload
may not get invoked when the system is shutting down, but the ProcessExit
will, and at the time it is invoked you still have full access to the entire
managed runtime.
Calling the GC::Collect() just before the termination of your application
won't change nothing to that. You can change this policy by calling the
function System.GC type's RequestFinalizeOnShutdown;

That may have been exposed in an early Beta but I cannot find a public
method or type of that name.
 
S

Sylvain Lafontaine

Thanks.

I've done a research on Google and the first results were about this old
Richter article, with other references linked themselves to this article. I
didn't notice that this article was now obsolete.

S. L.
 

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