2012-08-25 7 views
22

私は広範な静的メンバーを持つクラスを持っていますが、そのうちのいくつかはマネージオブジェクトとアンマネージドオブジェクトへの参照を保持します。C#静的メンバーはいつ、どのように処理されますか?

例えば、タイプが参照されるとすぐに静的コンストラクタが呼び出され、これにより、クラスがTasksのblockingQueueを回転させます。これは、たとえば静的メソッドの1つが呼び出されたときに発生します。

私はIDisposableを実装しました。これは、私が作成したインスタンスオブジェクトに対して処理を行うメソッドを提供します。ただし、コンシューマが自分のクラスからインスタンスオブジェクトを作成しない場合、これらのメソッドは呼び出されません。

私のクラスの静的部分によって保持されている参照を処分するコードをどのように配置するのですか?私はいつも、最後のインスタンスオブジェクトが解放されたときに静的参照されたリソースの廃棄が起こったと考えました。インスタンスを作成しないクラスを初めて作成したのはこれが初めてです。

+1

静的項目は、アプリケーションの全体の実行のために利用可能です。 NEWキーワードを使用して静的な項目を作成するわけではありません。つまり、実際には何もインスタンス化しないため、何も複数のインスタンスを持たないということです。管理対象オブジェクトについては、それらについて心配する必要はありません.GCがそれらを処理します。アンマネージリソースについては、静的でないクラスでそれらを使用しようとするか、アプリケーションを閉じるまで保持されます。静的項目は処理をサポートしていません。 – alexandrudicu

+0

ありがとうございます。私はここで私のデザインを再考する必要があるように見えます。 – Joe

答えて

35

クラスの静的変数は、クラスをホストするアプリドメインがアンロードされるまでガベージコレクションされません。 Dispose()メソッドはインスタンスメソッドであり、クラスのインスタンスを作成しないと言ったので、呼び出されません。

Dispose()メソッドを使用する場合は、オブジェクトをシングルトンにして1つのインスタンスを作成し、アプリケーションを終了するときに明示的に処分します。

public class MyClass : IDisposable { 
    public IList List1<int> {get; private set;} 
    public IDictionary<string,string> Dict1 {get; private set;} 
    public void Dispose() { 
     // Do something here 
    } 
    public static MyClass Instance {get; private set;} 
    static MyClass() { 
     Instance = new MyClass(); 
    } 
    public static void DisposeInstance() { 
     if (instance != null) { 
      Instance.Dispose(); 
      Instance = null; 
     } 
    } 
} 
+0

それは意味があります。私は最終的にシングルトンのパターンを使用しなければならないかもしれないと思った...あなたの助けに感謝します。 – Joe

0

このオブジェクトは手動で処分する必要があります。静的リソースの「ファイナライザ」を作成する方法はありません。

+1

どうすればそれらを手動で処分できますか?私はこれを行う必要があることをどのように通知されますか? – Joe

+0

@Joeそれはあなたが決めるのはあなた次第です。静的に保持されているものを処分するときは、あなただけが知っている。 – vcsjones

+0

たとえば、私はActionsのblockingQueueをスピンアップする元の質問の例を参照してください。このキューは、ユーザーがもはや静的メソッドを使用してアクションをドロップする必要がなくなるまで実行されます。 もっと明確にしましょう。キューを排水する仕事はいつ中止しますか? だから、いつ私はそれを殺すのですか?私のクラスがもはやユーザーの「範囲」に入っていないことをどのようにして知ることができますか? – Joe

0
public class Logger : IDisposable 
{ 

    private string _logDirectory = null; 
    private static Logger _instance = null; 

    private Logger() : this(ConfigurationManager.AppSettings["LogDirectory"]) 
    { 
     AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; 
    } 

    private Logger(string logDirectory) 
    { 
    } 

    public static Logger Instance 
    { 
     get 
     { 
      if (_instance == null) 
       _instance = new Logger(); 
      return _instance; 
     } 
    } 

    private void CurrentDomain_ProcessExit(object sender, EventArgs e) 
    { 
     Dispose(); 
    } 



    public void Dispose() 
    { 
     // Dispose unmanaged resources 
    } 
} 
関連する問題