web-dev-qa-db-ja.com

C#静的メンバーはいつどのように破棄されますか?

広範な静的メンバーを持つクラスがあり、その一部は管理オブジェクトおよび非管理オブジェクトへの参照を保持しています。

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

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

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

32
Joe

クラスの静的変数は、クラスをホストしているアプリドメインがアンロードされるまでガベージコレクションされません。 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;
        }
    }
}
49
dasblinkenlight
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
    }
}
3
Guido Kleijer

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

0
oxilumin