C⻠資源放出方法の実例分析


本論文の実例はC荪資源放出方法を述べている。皆さんに参考にしてあげます。具体的には以下の通りです。
1、try{finally}
2、using
タイプのみがIDisposableインターフェースを実現し、Dispose()を書き換える方法は、using文を使用してリソースリリースを実現することができる。
まずMSDNにおけるこのインターフェースに関する説明を見ます。

[ComVisible(true)]
public interface IDisposable
{ // Methods
void Dispose();
}

1.「Commvieble(true)」:
このホストタイプはCOMに対して表示されます。
2.このインターフェースの主な用途は、非委託管理の資源を解放することである。
ホステルオブジェクトを使用しない場合、ゴミ回収器は自動的に対象に割り当てられたメモリを解放します。しかし、ゴミの回収時間は予測できません。また、ゴミ回収器は、窓口のハンドルや開いているファイルやストリームなどの非委託資源については知らない。このインターフェースのDispose方法をごみ箱と一緒に使用して、非委託資源を明示的に釈放します。オブジェクトが必要でない場合、オブジェクトの使用者はこの方法を呼び出すことができます。
一、基本的な応用
1.IDisposableインターフェースを実現したクラスを定義します。コードは以下の通りです。

public class TestClass :IDisposable
{
  public void DoSomething()
  {
    Console.WriteLine("Do some thing....");
  }
  public void Dispose()
  {
    Console.WriteLine("      ");
  }
}

2.呼び出しには2つの方法があります。
2.1.第一の方式では、Using文を使用すると、Disposeメソッドを自動的に呼び出します。コードは以下の通りです。

using (TestClass testClass = new TestClass())
{
  testClass.DoSomething();
}

2.2第二の方式は、このインターフェースのDispose方法を現実的に呼び出し、コードは以下の通りである。

TestClass testClass = new TestClass();
try {
  testClass.DoSomething();
}
finally
{
  IDisposable disposable = testClass as IDisposable;
  if (disposable != null)
  disposable.Dispose();
}

二つの方式の実行結果は同じです。
2.3.try/catch/finallyを使用する利点は、捕獲異常後に処理が可能になり、同時に資源も解放されることである。しかし、USingを使用して、異常があっても資源を解放することができます。異常を処理することができないだけで、直接に異常を放行します。実際にこの2つの方法は資源の放出に対して同じです。
二、Dispposableモード
1.NETでは、オブジェクトがアクセス不可になったら自動的にFinalizeメソッドを呼び出すので、IDisposableインターフェースを手動で呼び出すDispose方法とオブジェクト終端器が呼び出す方法は極めて似ています。彼らを一緒に処理したほうがいいです。
まず思いついたのはFinalizeを書き換える方法です。

protected override void Finalize()
{
  Console.WritleLine("      ...");
}

このコードをコンパイルすると、コンパイラは親のFinalizeメソッドを徹底的に遮断しています。コンパイラはFinalize方法を書き換えるなら、代わりにコンフィギュレーション関数を提供したいと警告しています。
~TestClass(){Consone.WriteLine(「コンストラクション実行...」);
実際にはこのコンストラクタは次のコードに変換されます。

protected override void Finalize()
{
  try {
    Console.WritleLine("      ...");
  }
  finally {
    base.Finalize();
  }
}

2.そして、Disposeメソッドの呼び出しと対象の終端器を一緒にして、次のように処理することができます。

public class TestClass: IDisposable
{
  ~TestClass()
  {
    Dispose();
  }
  public void Dispose()
  { //     
  }
}

3.上記の実施形態は実際にDispose方法とFinalize方法を呼び出しました。このように重複したクリーンアップ作業につながる可能性がありますので、下記のような古典的なDispopsableモードがあります。

private bool _isDisposed = false;
public void Dispose()
{
  Dispose(true);
  GC.SupressFinalize(this);
}
protected void Dispose(bool Diposing)
{
  if(!_isDisposed)
  {
    if(Disposing)
    {
      //      
    }
    //       
  }
  _isDisposed=true;
}
~TestClass()
{
  Dispose(false);
}

3.1.Supress Finalize方法は、ごみ回収器が終了する必要がないオブジェクトに対してObject.Finalize()を呼び出すことを防止する。
3.2.IDisposable.Disppose方法を使用して、ユーザは対象をゴミとして回収できる前にいつでも資源を放出することができる。IDisposable.Dispposeメソッドが起動されたら、この方法はオブジェクトのリソースを解放します。これで中止する必要はない。IDisposable.Dispposeは、GC.Suppres Finalizeを呼び出して、ゴミ回収器を対象の終端器を呼び出さないようにします。
3.3.私たちはDisposeメソッドが外部に呼び出されることを望まないので、彼の訪問レベルはprotectedです。Diposingがtrueであれば、委託資源と非委託資源を解放し、Diposingがfalseに等しい場合、この方法はすでに運行ライブラリによってエンドエフェクタ内部から呼び出され、非委託資源のみを解放する。
3.4.オブジェクトがリリースされた後に他の方法を呼び出すと、Object DiscposedExceptionを誘発する可能性があります。
三、実例解析
1.以下のコードはDispose方法をカプセル化していますが、どのようにホストと本マシンのリソースのクラスでDispose(book)を実現するかを説明しています。

public class BaseResource : IDisposable
{
  //      
  private IntPtr _handle;
  //    
  private Component _components;
  // Dispose     
  private bool _disposed = false;
  public BaseResource() { }
  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }
  protected virtual void Dispose(bool disposing)
  {
    if (!this._disposed)
    {
      if (disposing)
      {
        //       
        _components.Dispose();
      }
      //        ,  disposing false,           
      CloseHandle(_handle);
      _handle = IntPtr.Zero;
      //            
    }
    _disposed = true;
  }
  //                Dispose       
  //               
  ~BaseResource() { Dispose(false); }
  //         Dispose             ObjectDisposedException
  public void DoSomething()
  {
    if (this._disposed)
    {
      throw new ObjectDisposedException();
    }
  }
}
public class MyResourceWrapper : BaseResource
{
  //     
  private ManagedResource _addedManaged;
  //      
  private NativeResource _addedNative;
  private bool _disposed = false;
  public MyResourceWrapper() { }
  protected override void Dispose(bool disposing)
  {
    if (!this._disposed)
    {
      try
      {
        if (disposing)
        {
          _addedManaged.Dispose();
        }
        CloseHandle(_addedNative);
        this._disposed = true;
      }
      finally
      {
        base.Dispose(disposing);
      }
    }
  }
}

2.CLRゴミ収集器を使って、どのように管理するか心配しなくてもいいです。他の種類の資源を整理してください。委託管理類はIDisposableインターフェースを通じて、使用者がごみ収集器が対象を終了する前に重要な資源を放出できるようにする。disposableモードに従って、注意すべき問題に留意することによって、クラスはそのすべてのリソースが正確に整理されることを確保でき、直接Disposableを通じて呼び出したり、終了スレッドを通してコードを整理したりする時には何の問題も発生しません。
ここで述べたように、皆さんのC〓プログラムの設計に役に立ちます。