Как и когда утилизировать / собирать мусор в одном экземпляре - PullRequest
5 голосов
/ 16 января 2012

Я использую экземпляр Singleton, созданный из вложенного класса.Этот экземпляр содержит несколько статических коллекций, которые очищаются при удалении Singleton, но проблема в том, что я получаю ссылку на ненулевой избавленный Singleton, который не собирается должным образом.

Я хотел бы знать WHEN и HOWдля полного удаления и сбора мусора моего экземпляра Singleton, чтобы при повторном запросе экземпляра после удаления (и установки значения null) был создан новый экземпляр.

Я использую следующий вложенный шаблон для экземпляра Singleton:

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;
    }    
}

Проблема в строке 1 заключается в том, что после удаления SingletonClass из клиентского класса объект _collection становится нулевым, а экземпляр SingletonClass остается ненулевым даже после установки = null.

1 Ответ

4 голосов
/ 16 января 2012

Вам нужно будет реализовать System.IDisposable, только если вы выполните следующие основные требования:

Основное использование этого интерфейса - освобождение неуправляемых ресурсов.

Тогда я бы пошел за деструктором класса и позвонил бы Dispose() в примере .

В противном случае

Сборщик мусора автоматически освобождает память, выделенную для управляемый объект, когда этот объект больше не используется.

(что не будет с реальным синглтоном, если процесс не завершится)

Вам может быть лучше, если вы используете что-то вроде этого

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;
        }
    }
}
...