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

Статический финализатор

Каков правильный способ выполнения некоторой статической финализации?

Нет статического деструктора. Событие AppDomain.DomainUnload не отображается в домене по умолчанию. Событие AppDomain.ProcessExit разделяет общее время трех секунд (настройки по умолчанию) между всеми обработчиками событий, поэтому оно не может использоваться.

4b9b3361

Ответ 1

В принципе, вы не можете. Создайте свой путь вокруг него в максимально возможной степени.

Не забывайте, что программа всегда может резко прекратиться - кто-то вытаскивает силу, являющуюся очевидным примером. Итак, все, что вы делаете, должно быть "наилучшим усилием", и в этом случае я, конечно, надеюсь, что AppDomain.ProcessExit будет достаточно хорошим.

Что вам нужно делать в вашем конкретном случае?

Ответ 2

Herfried Wagner написал отличную статью, объясняющую, как реализовать это - увы, на немецком (и VB). Тем не менее, код должен быть понятным.

Я пробовал:

static readonly Finalizer finalizer = new Finalizer();

sealed class Finalizer {
  ~Finalizer() {
    Thread.Sleep(1000);
    Console.WriteLine("one");
    Thread.Sleep(1000);
    Console.WriteLine("two");
    Thread.Sleep(1000);
    Console.WriteLine("three");
    Thread.Sleep(1000);
    Console.WriteLine("four");
    Thread.Sleep(1000);
    Console.WriteLine("five");
  }
}

Кажется, что он работает точно так же, как это делает событие AppDomain.ProcessExit: финализатор получает ок. три секунды...

Ответ 3

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

Тем не менее, ваш статический метод может создать объект, который имеет метод finalize.

Ответ 4

Два решения, которые приходят в голову:

  • Не используйте статический класс. Если вы используете нестатический класс и создаете его, вам не нужно беспокоиться об очистке.
  • Если это не вариант, я бы сказал, что это хорошая ситуация для использования синглтона. Это создаст экземпляр копии вашего объекта и вызовет финализатор при выходе, но по-прежнему позволит вам рассматривать его как статический класс по большей части. В конце концов, ваш класс уже статичен и поэтому разделяет большинство распространенных причин не использовать синглтон.

Ответ 5

Отправлять Майклу Даматову ответ (С#), который основан на Херфриде К. Вагнере. (VB.NET) вот версия С++/CLI:

ref class MyClass
{
        ref class StaticFinalizer sealed
        {
            !StaticFinalizer();
        };
        static initonly StaticFinalizer^ stDestr = gcnew StaticFinalizer();
}

MyClass::StaticFinalizer::!StaticFinalizer()
{
    System::Diagnostics::Debug::WriteLine("In StaticFinalizer!");
}

P.S. Подобно методу AppDomain.ProcessExit, этот вызов нельзя вызывать, если процесс прерывается ненормально (например, из диспетчера задач). Еще одно предостережение заключается в том, что если MyClass является общим (templated), предположение о том, что его статический конструктор и статический деструктор будет вызываться не более одного раза на выполнение приложения, больше недействительно.