C# 静态终结器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/256077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Static Finalizer
提问by Michael Damatov
What is the right way to perform some static finallization?
执行一些静态终结的正确方法是什么?
There is no static destructor. The AppDomain.DomainUnload
event is not raised in the default domain. The AppDomain.ProcessExit
event shares the total time of the three seconds (default settings) between all event handlers, so it's not really usable.
没有静态析构函数。该AppDomain.DomainUnload
事件不会在默认域中引发。该AppDomain.ProcessExit
事件在所有事件处理程序之间共享三秒(默认设置)的总时间,因此它实际上并不可用。
采纳答案by Jon Skeet
Basically, you can't. Design your way around it to the fullest extent possible.
基本上,你不能。尽可能地围绕它设计你的方式。
Don't forget that a program can alwaysterminate abruptly anyway - someone pulling out the power being the obvious example. So anything you do has to be "best effort" - in which case I'd certainly hopethat AppDomain.ProcessExit
would be good enough.
不要忘记,无论如何,程序总是会突然终止——有人拔掉电源就是一个明显的例子。所以你所做的任何事情都必须是“尽力而为”——在这种情况下,我当然希望这AppDomain.ProcessExit
足够好。
What do you need to do, in your particular case?
在您的特定情况下,您需要做什么?
回答by Ady
I would question what you are loading in your static methods that need to be released. I certainly wouldn't recommend doing these things in a static method.
我会质疑您在需要释放的静态方法中加载了什么。我当然不会推荐在静态方法中做这些事情。
That said, your static method could instanciate an object that has a finalise method.
也就是说,您的静态方法可以实例化具有 finalize 方法的对象。
回答by Jason Baker
Two solutions that jump to mind:
想到的两种解决方案:
- Don't use a static class. If you use a non-static class and instantiate it, you don't have to worry about cleanup as much.
- If that's not an option, I'd argue that this is a good situation to use a singleton. This will instantiate a copy of your object and have the finalizer called on exit, but still allow you to treat it like a static class for the most part. After all, your class is static already and therefore shares most of the common reasons not to use a singleton.
- 不要使用静态类。如果您使用非静态类并实例化它,则不必担心清理。
- 如果这不是一个选项,我认为这是使用单例的好情况。这将实例化对象的副本并在退出时调用终结器,但仍然允许您在大多数情况下将其视为静态类。毕竟,您的类已经是静态的,因此分享了不使用单例的大多数常见原因。
回答by Michael Damatov
Herfried Wagner has written an excellent articleexplaining how to implement this – alas, in German (and VB). Still, the code should be understandable.
Herfried Wagner 写了一篇出色的文章,解释了如何实现这一点——唉,用德语(和 VB)。不过,代码应该是可以理解的。
I've tried it:
我试过了:
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");
}
}
It seems to work exactly the same way as the AppDomain.ProcessExit
event does: the finalizer gets ca. three seconds...
它的工作方式似乎与AppDomain.ProcessExit
事件完全相同:终结器获得 ca。三秒...
回答by ILIA BROUDNO
To port Michael Damatov's answer (C#) which is based on Herfried K. Wagner. (VB.NET) here is the C++/CLI version:
移植基于 Herfried K. Wagner 的 Michael Damatov 的答案 (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!");
}
P.S. Just like the AppDomain.ProcessExit method, this one may not be called if the process is terminated abnormally (from Task Manager for example). Another word of caution is that if MyClass is generic (templated), the assumption that its static constructor and static destructor will be called no more than once per application execution is no longer be valid.
PS 就像 AppDomain.ProcessExit 方法一样,如果进程异常终止(例如从任务管理器中),可能不会调用该方法。另一个注意事项是,如果 MyClass 是泛型(模板化),则每次应用程序执行其静态构造函数和静态析构函数将被调用不超过一次的假设不再有效。