Подтвердить что ты не робот

Как и когда С# статические члены расположены?

У меня есть класс с обширными статическими членами, некоторые из которых содержат ссылки на управляемые и неуправляемые объекты.

Например, статический конструктор вызывается, как только ссылается на Type, что заставляет мой класс вызывать блокировкуQueue of Tasks. Это происходит, например, когда вызывается один из статических методов.

Я реализовал IDisposable, который дает мне методы для обработки удаленных объектов, которые я создал. Однако эти методы никогда не вызывают, если потребитель не создает объекты экземпляра из моего класса.

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

4b9b3361

Ответ 1

Статическая переменная вашего класса не собирает мусор до тех пор, пока домен приложения, на котором размещен ваш класс, не будет выгружен. Метод Dispose() не будет вызываться, потому что это метод экземпляра, и вы сказали, что не будете создавать экземпляры своего класса.

Если вы хотите использовать метод Dispose(), сделайте свой объект одиночным, создайте один экземпляр его и удалите его явно, когда ваше приложение вот-вот выйдет.

public class MyClass : IDisposable {
    public IList List1<int> {get; private set;}
    public IDictionary<string,string> Dict1 {get; private set;}
    public void Dispose() {
        // Do something here
    }
    public static MyClass Instance {get; private set;}
    static MyClass() {
        Instance = new MyClass();
    }
    public static void DisposeInstance() {
        if (instance != null) {
            Instance.Dispose();
            Instance = null;
        }
    }
}

Ответ 2

Вы должны удалять эти объекты вручную, нет никакого способа создать "финализатор" для статических ресурсов.

Ответ 3

public class Logger : IDisposable
{

    private string _logDirectory = null;
    private static Logger _instance = null;

    private Logger() : this(ConfigurationManager.AppSettings["LogDirectory"])
    {
        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
    }

    private Logger(string logDirectory) 
    {
    } 

    public static Logger Instance
    {
        get
        {
            if (_instance == null)
                _instance = new Logger();
            return _instance;
        }
    }

    private void CurrentDomain_ProcessExit(object sender, EventArgs e)
    {
        Dispose();
    }



    public void Dispose()
    {
        // Dispose unmanaged resources
    }
}

Ответ 4

Если вы действительно хотите иметь статические члены, которые сохраняют ссылки на неуправляемые объекты, просто создайте метод для удаления неуправляемых объектов и "заставьте" потребителя использовать его при выходе.

Под "силой" я подразумеваю документ вашего класса с параграфом, в котором говорится "когда" и "почему" использовать этот метод "распоряжаться". Сделайте это, если вы являетесь единственным потребителем (или вашим кодом...) или планируете распространять свой класс. Также попробуйте использовать как-нибудь описательное имя (для этого метода "dispose"), например "DisposeStatics", "AlwaysDispose", "DisposeAtEnd" и т.д.