静的ファイナライズを実行する正しい方法は何ですか?
静的デストラクタはありません。 AppDomain.DomainUnload
イベントはデフォルトドメインでは発生しません。 AppDomain.ProcessExit
eventは、すべてのイベントハンドラー間で3秒(デフォルト設定)の合計時間を共有するため、実際には使用できません。
基本的にはできません。可能な限りそれを回避する方法を設計します。
プログラムが常にとにかく突然終了する可能性があることを忘れないでください-誰かが力を引き出しているのは明らかな例です。したがって、あなたがすることはすべて「ベストエフォート」でなければなりません-その場合、私は確かに希望その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
イベントとまったく同じように機能するようです。ファイナライザーは約を取得します。 3秒...
頭に浮かぶ2つの解決策:
解放する必要のある静的メソッドに何をロードしているのか疑問に思います。私は確かにこれらのことを静的な方法で行うことをお勧めしません。
そうは言っても、静的メソッドは、finalizeメソッドを持つオブジェクトをインスタンス化する可能性があります。
Herfried K.Wagnerに基づくMichaelDamatovの回答(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. AppDomain.ProcessExitメソッドと同様に、プロセスが異常終了した場合(たとえば、タスクマネージャーから)、このメソッドは呼び出されない場合があります。もう1つの注意点は、MyClassが汎用(テンプレート)の場合、その静的コンストラクターと静的デストラクタがアプリケーションの実行ごとに1回だけ呼び出されるという仮定は無効になるということです。