Destructors in C# are very different from C++ destructors. They are not actual destructors that are run on fully correct objects which are no longer required, but a last resort measure to deal with unmanaged resources (MSDN):
You should override Finalize for a class that uses unmanaged resources
such as file handles or database connections that must be released
when the managed object that uses them is discarded during garbage
collection.
So it is a bad idea to use Finalizer (Destructor) to interoperate with managed resources, because:
The finalizers of two objects are not guaranteed to run in any
specific order, even if one object refers to the other. That is, if
Object A has a reference to Object B and both have finalizers, Object
B might have already been finalized when the finalizer of Object A
starts.
Deserialized data list may be correct during such finalization, or it may have been already reclaimed during previous GC runs. Even if it is not so with current garbage collector, no one can guarantee that such problem won't appear in the next .NET version. Accessing managed resources in Finalizer's is practically an undefined behaviour.
Possible solution
Taking into account that your object is singleton, and thus it can be garbage collected only when application exits (or never if it is never requested),
the simplest way to allow such persistent storage to object's data is to attach event handler to the application close(exit) event.
...
public static Singleton Instance
{
get
{
if (_Instance == null)
{
_Instance = new Singleton();
Application.Exit += (sender, args) =>
{
_Instance.SaveChanges();
}
}
return _Instance;
}
}
Or use appropriate Lazy<T>
constructor if your Singleton is based on its use.