0

Dispose Patternを完全に正しく使用する方法に関する短い質問。Dispose メソッドでマネージド リソースを破棄しています。

しかし、使い捨てではないオブジェクトはどうですか?のように、または...StringSystem.Text.Decoder

これらのオブジェクトを正しく処理するにはどうすればよいですか? nullGC にそれらをファイナライズさせない場合にそれらを設定しないとどうなりますGC.SupressFinalize(this);か?

パターンを実装する方法の例を次に示します。

  private class RequestState : IDisposable {
    const int BufferSize = 1024;
    public StringBuilder RequestData;
    public byte[] BufferRead;
    public WebRequest Request;
    public Stream ResponseStream;
    // Create Decoder for appropriate enconding type.
    public Decoder StreamDecode = Encoding.UTF8.GetDecoder();
    public MyMamespace.Machine Machine;

  public RequestState() {
    BufferRead = new byte[BufferSize];
    RequestData = new StringBuilder(String.Empty);
    Request = null;
    ResponseStream = null;
  }
-------------------------------------------------------------------------------
  #region IDisposable
  private bool disposed = false;

  public void Dispose() {
    Dispose(true);
  }

  #region IDisposable
  private bool disposed = false;

  public void Dispose() {
    Dispose(true);
    // GC.SupressFinalize(this);         // What happens if I tell the GC that this object is alredy finalized??
  }

  protected virtual void Dispose(bool disposing) {
    if ( !this.disposed ) {
      if ( disposing ) {
        // Dispose managed resources.
        ResponseStream.Dispose();
        Machine = null;                 // Do I need this?
      }
      // release unmanaged ressources

      disposed = true;
    }
  }

  ~RequestState() {
    Dispose(false);
  }
  #endregion
}
#endregion
4

2 に答える 2

3

それらが使い捨てパターンを実装していない場合、それらのクラスの作成者は「これらのものは特別なクリーンアップを必要としない」と言っています。

また、どちらも割り当てる必要はありません-GCnullの要点は、使用されなくなったものを見つけることです-「それを助ける」ことを試みる必要はありません(そして、それらがで効果がある場合は多くの努力)すべて、実際には GC を妨げます)

GC.SupressFinalize()クラス1の作成者ではないオブジェクトを呼び出すべきではありません。


1そして今、私が現在考えていないいくつかのエッジケースを指摘するコメントを待っています.

于 2013-10-16T06:20:15.597 に答える
1

への参照を明示的に設定する必要はありませんがnull、そうすると、インスタンスが破棄された後も引き続き参照されている場合でも、それらのインスタンスをガベージ コレクションできます。

私の個人的な意見では、null参照が不要になったときに参照を設定することは、バグを見つけるのに役立つため、良い習慣です。

Disposable パターンを実装し、オブジェクトにファイナライザーがGC.SuppressFinalize()ある場合は、メソッド内で常にインスタンスを呼び出す必要がありますDispose。これにより、インスタンスは既に破棄されているため、インスタンスのファイナライザーを呼び出す必要がないことがランタイムに通知されます。

呼び出しGC.SupressFinalize()によって、ガベージ コレクターが収集される可能性のあるインスタンスを "見逃す" ことはありません。

于 2013-10-16T06:28:41.300 に答える