13
  • static使い捨てアイテムを使用したクラスはどのように管理すればよいですか? 経験則はありますか?

  • 基本的にはリファクタリングして以下のようなDisposableDataManagerクラスにするべきですか、それともnon- staticおまかせでいいのGCでしょうか?

.

public static class DisposableDataManager
{
    // ImageList is an 'IDisposable'.
    public static ImageList FirstImageList { get; private set; }
    public static ImageList SecondImageList { get; private set; }

    static DisposableDataManager()
    {
        FirstImageList = CreateFirstImageList();
        SecondImageList = CreateSecondImageList();        
    }

    // ...
}
4

7 に答える 7

18

それは、リソースが処分されることがあなたにとってどれほど重要であるかに大きく依存します. アプリケーションが閉じられると、それが開いていたすべてのハンドル (ファイル、ネットワーク接続、グラフィックスなど) はとにかく解放されるので問題はありません。より整然としたリリースのために処理が必要な場合は、さらに問題になります。たとえば、ストリームを閉じる前にフラッシュします。CLR は、プロセスが終了する前にファイナライザーを実行するための「最善の努力」を行います。これは、場合によっては呼び出さDisposeますが、重要なことに依存したいものではありません。

したがって、ImageListオブジェクトの場合、実際には問題になりません。リソースがリークすることは絶対にありません。オペレーティング システムが処理します。

そうは言っても、私はまだリファクタリングを試みます-単純に、グローバルな状態は悪い考えになる傾向があるからです. 依存関係が暗黙的になり、テストが難しくなります。構築時に必要な各オブジェクトに関連情報を提供するのはどれほど難しいでしょうか?

AppDomain(注:静的変数は、プロセス全体ではなく実際に関連付けられています。これにより、 AppDomains が起動および停止されるアプリケーションでは、問題全体がより複雑になりますが、それがあなたのシナリオに関連しているとは思えません。)

于 2012-08-31T06:06:46.907 に答える
5

静的クラスとして、あなたはすべてがアプリケーションで利用可能であると言っています。では、なぜあなたはそれを処分したいと思うのでしょうか?

于 2012-08-23T13:28:44.410 に答える
2

AppDomain.DomainUnload イベントをフックして、終了する前に確実にクリーンアップしたいものに対して dispose を呼び出すことができます。

于 2012-08-23T13:37:44.377 に答える
0

あなたの現在の作業方法はうまくいくと思いますが、あなたのプログラムが何をしようとしているのかを解決するためのより良い方法は間違いなくあります. それが機能する場合、それは言語の乱用になります-意図されたものに対して機能を使用します.

このアーキテクチャ パスを続行すると、コードの理解と変更が難しくなります。

この方法で求めていることを書き留めて、別のアイデアを求めることはおそらく価値があるでしょう.

于 2012-08-30T20:38:56.633 に答える
0

そのコードからわかることは、アプリが閉じられるまでアクセスできる静的クラスであるImageListため、破棄できないことです。DisposableDataManager

于 2012-08-29T17:44:30.547 に答える
-1

とにかく、使い捨て可能なリソースを静的クラスに保持しないでください。プログラムが終了した場合(たとえば、プログラムがクラッシュした場合)に破棄される可能性は低いためです。したがって、アプリケーションが実行されている限り存在するオブジェクトで、自分でリソースを追加および解放する可能性があります。

  • プログラム ループに入る前に、using ステートメントでラップされます。
  • または、自分で処理し、プログラムが終了したらすぐに final コンストラクトで dispose を呼び出します。

または、ImageList をまったく破棄できないように変更することもできます。これは、保持しているすべてのリソースを自分で処分できる場合にのみ選択できます。

于 2012-08-23T13:32:10.347 に答える
-2

使い捨てオブジェクトマネージャーを行う必要はないと思います。GC はすでにメモリを管理しています。ご存知かもしれませんが、Dispose メソッドは、.Net フレームワークに含まれる IDisposable インターフェイスから派生したものです。しかし、それは他の方法と同じです*。ガベージ コレクターは、オブジェクトのメモリを解放するために Dispose が呼び出されるのを待ちません。彼は、オブジェクトが常にどこかから到達可能かどうかを監視します。これは、どのオブジェクトが生きていて、どのオブジェクトが死んでいるかを判断するのに役立ちます。

続行する前に、GC 生成について少し読んでください。http://msdn.microsoft.com/en-us/library/ms973837.aspx

よくわかりませんが、new() が呼び出され、GC が実際に使用されている世代の容量に達すると、彼は次世代の「死んだ」オブジェクトをクリアします。おそらく私がそうしない他の時には。GC は非常に神秘的でミステリアスな実装です。おそらく C++ で処理されているからです。しかし、あなたはそれを気にする必要はありません。

場合によっては(モノ現像)、もっと気にした方がいいと聞きました。ただし、Microsoft 環境でコーディングする場合はそうではありません。

*私は言った:

他の方法と同じように

ただし、using ブロックを使用すると、IDisposable オブジェクトの Dispose メソッドを呼び出す必要がなく、そのメソッドを呼び出す自由が得られます。メソッド Dispose の既存の存在は、オブジェクトの使用を停止する前に解放する必要があるリソースを解放することです。

元:

    public class Test : IDisposable
    {
        public void Dispose()
        {
            // release other necessary ressources if needed

            Console.WriteLine("Disposed");
        }
    }


    {
        using (IDisposable disposable = new Test())
        {

        }
    }

と同じ:

{
    IDisposable disposable = new Test()
    disposable.Dispose();
}

そのため、GC に自信を持つことができます。GC が確実にオブジェクト メモリを解放するようにしたい場合は、オブジェクトへのすべての参照を null にします。そしてGCはあなたのオブジェクトを「死んでいる」と見なします:P

于 2012-08-28T02:22:55.253 に答える