I tried to further narrow down the problem in Flush StreamWriter at the end of its lifetime implementing a singleton-like self-closing StreamWriter
:
class Foo : System.IO.StreamWriter
{
private static readonly Foo instance = new Foo( "D:/tmp/test" );
private Foo( string path )
: base( path )
{
}
~Foo()
{
this.Close();
}
public static Foo Instance
{
get
{
return instance;
}
}
}
The intended effect is that in a sample program like
class Program
{
private static void Main( string[] args )
{
Foo.Instance.Write( "asdf\n" );
}
}
the garbage collector causes the instance of Foo
to be closed.
This does not work. Apparently, the StreamWriter
is already gone when Foo
's destructor runs, and I get a System.ObjectDisposedException
.
How do I call Close()
on the stream in an appropiate way and prevent loss of data?
Apparently, the StreamWriter is already gone when Foo's destructor runs
Yes. At program termination, assuming your object gets GC'ed at all (there's no guarantee it will be), the runtime doesn't provide any guarantees about the order in which it executes finalizers. Both objects are unreachable and eligible for finalization at the same time, and so their finalizers could run in any order.
Finalizers are there only as a backstop for buggy code. And they are not 100% reliable for that purpose either. It's why you should work hard to avoid buggy code.
You'll need a deterministic way to dispose the singleton object on process exit. You can put this into the control of your program's main logic, which is controlling the process lifetime, and have it dispose the singleton (e.g. via a public method you write for that purpose). Another alternative is to subscribe to the AppDomain.ProcessExit
event in your singleton's constructor, and have the handler close the singleton there.
See these related questions for additional information:
How can I ensure that I dispose of an object in my singleton before the application closes?
Disposable singleton in C#