静态终结器
什么是正确的方式来执行一些静态finallization?
没有静态析构函数。 AppDomain.DomainUnload
事件不在默认域中引发。 AppDomain.ProcessExit
事件共享所有事件处理程序之间三秒(默认设置)的总时间,所以它不是真的可用。
基本上,你不能。 尽可能devise你的方式。
不要忘记,无论如何,一个程序可以总是突然终止 – 有人拔出权力是一个明显的例子。 所以你所做的任何事情都必须是“尽力而为” – 在这种情况下,我当然希望 AppDomain.ProcessExit
足够好。
你需要做什么,在你的具体情况?
瓦格纳(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
事件一样工作:终结器获取CA. 三秒钟…
我会怀疑你正在加载你需要发布的静态方法。 我当然不会build议在静态方法中做这些事情。
也就是说,你的静态方法可以instanciate具有finalize方法的对象。
想到两个解决scheme:
- 不要使用静态类。 如果您使用非静态类并实例化它,则不必担心清理过多。
- 如果这不是一个选项,我认为这是一个很好的情况下使用一个单身人士。 这将实例化对象的副本,并在退出时调用终结器,但仍然允许将它视为大多数静态类。 毕竟,你的课程已经是静态的了,因此它拥有大部分不使用单例的常见原因。
为了移植Michael Damatov的基于Herfried K. Wagner的答案(C#)。 (VB.NET)这里是C ++ / CLI版本:
ref class MyClass { ref class StaticFinalizer sealed { !StaticFinalizer(); }; static initonly StaticFinalizer^ stDestr = gcnew StaticFinalizer(); } MyClass::StaticFinalizer::!StaticFinalizer() { System::Diagnostics::Debug::WriteLine("In StaticFinalizer!"); }
PS就像AppDomain.ProcessExit方法一样,如果进程exception终止,则可能不会调用这个方法(例如,从任务pipe理器)。 另一个值得警惕的是,如果MyClass是通用的(模板化的),那么假设它的静态构造函数和静态析构函数在每个应用程序执行中被调用的次数不再是有效的。