I am using a Singleton instance created out of a nested class. This instance holds some static collections which are cleared when the Singleton is disposed, but the problem is I get a reference to non-null disposed Singleton which is not properly garbage collected.
I would like to know WHEN and HOW to completely dispose and garbage collect my Singleton instance so that when the instance is queried again after dispose (and setting to null) a new Instance is created.
I am using the following nested pattern for Singleton instance:
public class SingletonClass : IDisposable
{
private List<string> _collection;
private SingletonClass()
{
}
public static SingletonClass Instance
{
get
{
return Nested.Instance; //line 1 - this line returns the non-null instance after dispose and setting the Singleton instance to null which is causing problems
}
}
private void Init()
{
_collection = new List<string>();
//Add data to above collection
}
public void Dispose()
{
//Release collection
_collection.Clear();
_collection = null;
}
class Nested
{
static Nested()
{
Instance = new SingletonClass();
Instance.Init();
}
internal static readonly SingletonClass Instance;
}
}
The problem at line 1 is that after dispose of SingletonClass from client class, the _collection object becomes null while the SingletonClass instance remains non-null even after setting = null.
You'll only need to implement System.IDisposable
if you fulfill following basic requirement:
The primary use of this interface is to release unmanaged resources.
Then I would go for the destructor of the class and call Dispose()
in the example.
Otherwise
The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used.
(which won't be the case with a real singleton, unless the process ends)
You may be better off, if you are using sth like this
class PseudoSingleton<T>
where T : new()
{
private readonly object _lock = new object();
private T _instance;
public T Instance
{
get
{
lock (this._lock)
{
if (this._instance != null)
{
this._instance = new T();
}
return this._instance;
}
}
}
public void Reset()
{
lock (this._lock)
{
this._instance = null;
}
}
}