Статический финализатор
Каков правильный способ выполнения некоторой статической финализации?
Нет статического деструктора. Событие AppDomain.DomainUnload
не отображается в домене по умолчанию. Событие AppDomain.ProcessExit
разделяет общее время трех секунд (настройки по умолчанию) между всеми обработчиками событий, поэтому оно не может использоваться.
Ответы
Ответ 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), предположение о том, что его статический конструктор и статический деструктор будет вызываться не более одного раза на выполнение приложения, больше недействительно.