2010-12-06 6 views
54

c#には初期化を行う静的コンストラクタがあります。 (可能性がありますいくつかの管理されていないリソースの初期化)私は静的なdestuctorがあるのだろうか?静的デストラクタ

+1

+1この面白いコメントは、leppieです。静的リソースはアプリケーションとほぼ同じ寿命を持つことを指摘したいと思います。彼らはアプリケーションが死ぬときに死ぬ。したがって、静的デストラクタは必要ありません。 – decyclone

+2

"静的デストラクタは必要ありません" - その2つの事柄はどう関係していますか?それは、appdomainがアンロードされているときにだけ起こるので、突然必要ではありませんか?私はそこに論理をたどるかどうか分からない。 – BrainSlugs83

答えて

27

いいえ、ありません。

静的デストラクタは、プロセスの実行終了時に実行されると考えられます。プロセスが終了すると、それに関連するすべてのメモリ/ハンドルがオペレーティングシステムによって解放されます。

実行終了時(トランザクションデータベースエンジンのようにキャッシュをフラッシュする)に特定のアクションを実行する必要がある場合は、最後に実行される単なるコードよりも処理がはるかに難しくなりますプロセスの通常の実行のプロセスのクラッシュや予期しない終了を手作業で処理し、次回の実行時にリカバリを試みる必要があります。 「静的デストラクタ」という概念はあまり役に立たないでしょう。

+4

私のケースでは、私はリリースが必要なOS全体のミューテックスを使用していた、またはアプリケーションの次の実行時にAbandonedMutexExceptionをスローします。この場合、プログラムの最後にリリースされたメモリとハンドルは、私のミューテックスを考慮していませんでした。あなたが第3段落で述べたことは、それを管理する方法かもしれませんが、アプリケーションのリリースの終わりは私にとって意味があるようでした。 – user1132959

10

いいえ、ありません。あなたができる最も近いことは、AppDomainDomainUnloadイベントにイベントハンドラ を設定し、そこでクリーンアップを実行することです。

+2

これは実際には、より高いupvotedの 'Process_Exit'提案に対する非常に好ましいアプローチです。これは全く異なっています。静的ctorが起動した後の型の有効期間は、通常、AppDomainでアンロードされるアセンブリの有効期間です。 – Abel

1

ありませんが、デストラクタのようなものは、静的なクラスのためではありませんが、あなたが本当に静的実装から何か

5

アンマネージリソースを初期化とクリーンアップを行う必要がある場合は、Appdomain.Unloadedイベントを使用することができますが、非常に問題と問題になりやすいです。

なぜシングルトンを使用して、例えばFinalizerを実装する(理想的にSafeHandleから継承)

78

ではなく、正確にデストラクタを、しかし、ここであなたがそれを行うだろうかではありません。

class StaticClass 
{ 
    static StaticClass() { 
     AppDomain.CurrentDomain.ProcessExit += 
      StaticClass_Dtor; 
    } 

    static void StaticClass_Dtor(object sender, EventArgs e) { 
     // clean it up 
    } 
} 
+1

が完璧です。私のために働く。 –

+1

イベント_seems_はAppDomain上にあるが、実際には、アプリケーション全体が終了する直前に、デフォルトのドメインが終了するとき(つまり、最後のドメイン)にのみ起動される。他のAppDomainがアンロードされたときに_それは_発火しません。それ自体が型のほとんどの型とインスタンスを破壊します(常にそうとは限りません)。このイベントは[常に発射することは保証されていません](http://blogs.msdn.com/b/jmstall/archive/2006/11/26/process-exit-event.aspx)。 – Abel

+1

静的インスタンスの分解に敏感なクリーンアップ操作を残さず、この推奨に従うことをお勧めします。このイベントは起動しないことを心配する必要はありません。このイベントが発生しなかった問題は、アプリケーションの予期しない例外が発生しても発生しませんでした。タスクマネージャを使用してプロセスを強制終了することは、予期しない例外とは大きく異なります。あなたは正しいですが、ユーザーがOSタスク管理システムを通してプログラムを殺すと起動しません。 –

48

この最高の方法です(参考:https://stackoverflow.com/a/256278/372666

public static class Foo 
{ 
    private static readonly Destructor Finalise = new Destructor(); 

    static Foo() 
    { 
     // One time only constructor. 
    } 

    private sealed class Destructor 
    { 
     ~Destructor() 
     { 
      // One time only destructor. 
     } 
    } 
} 
+2

この方法は動作することが保証されています! :)それを行ってください、誰かが興味があれば動作することを証明する単体テストがありますか? –

+2

が確認されました。魅力のように動作します。 –

+2

完璧な、非常に滑らかに働いた! – Steve

関連する問題