2

以下の使い捨てパターンはどうですか?

using System;
public class MyClass : IDisposable 
{     
    public void Dispose() 
        // Implement IDisposable     
    {
        //just do the cleanup
        GC.SuppressFinalize(this);
    } 

} 

アップデート

つまり、管理されていないリソースがない場合、ファイナライザーが必要ですか? 上記の使い捨てパターンで十分ではないでしょうか。はい、ユーザー/開発者が dispose を呼び出さない場合でも、GC はデフォルトで dispose を呼び出しませんか?

また、GC が dispose と finalizer を呼び出す順序についてはどうでしょうか?

詳細については、この質問を参照してください。

つまり、ファイナライザーがあるのに、なぜDisposefalse をパラメーターとして呼び出すのでしょうか?


http://msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2から、マネージド参照ではなく、ファイナライザーからアンマネージド リソースを解放することが常に推奨されるようです。

Dispose メソッドからアンマネージ リソースを解放することを常にお勧めします。記事を読んでも全体の要点はわかりませんでした。

ただし、管理されていないリソースがない場合は、以下のパターンが機能するはずです。


msdn.microsoft.com/en-us/magazine/cc163392.aspx#S2、msdn.microsoft.com/en-us/library/fs2xkftw.aspx によると、ネイティブ リソースをファイナライザーで解放し、それらすべてを dispose( )。dispose() が明示的に呼び出された場合、ファイナライザーを抑制することができます。つまり、ネイティブ リソースがない場合、ファイナライザーは必要ありません。

using System;
public class MyClass : IDisposable 
{ 
    private bool disposed = false;  
    protected virtual void Dispose(bool suppressFinalize) 
    {    
        if (!disposed)
        {
            //Just do the cleanup
            //and release resources
            disposed = true; 
        }
        if (!suppressFinalize)
        {
            GC.SuppressFinalize(this); 
        }
    }
    public void Dispose() 
        // Implement IDisposable     
    {
        Dispose(true);           
    } 
    ~MyClass() // the finalizer
    {     
        Dispose(false);    
    }
} 
4

2 に答える 2

13

管理されていないリソース (Windows ハンドルなど) への直接参照があり、誰も呼び出しなくてもそれらを解放したい場合があるためDisposeです。

ただし、これは非常にまれです。通常、必要に応じてファイナライザーを持つ他のマネージド型を介して、アンマネージド リソースへの間接参照しか実際にはありません。

于 2012-06-01T17:27:39.580 に答える
4

ファイナライズ + IDisposable.Net は、実際には 2 つの異なる問題であり、単一の使い捨てパターンで解決しようとしています。

  • 管理対象リソースのクリーンアップ
  • アンマネージ リソースのクリーンアップ

アンマネージド リソースは、CLR とガベージ コレクターの制御下にない項目です。ファイル ハンドル、PInvoke から返されたメモリなどの項目...これらのリソースがユーザー コードによって明示的に解放されていない場合、それらはリークし、プロセスの有効期間が終了するまで残ります。彼らが解放されることが重要です。

ここでファイナライザーの出番です。ファイナライザーは、オブジェクトが CLR によって収集される直前に実行されます。これは、消費者が破棄可能なパターンに従う必要がないため、管理されていないリソースを確実に解放してリークを防ぐための適切なフォールバックです。

コードに直接保持されているアンマネージド リソースが含まれていない場合、ファイナライザーを使用する理由はありません。ファイナライザーを持つのは、アンマネージ リソースを保持するコードの責任です。

于 2012-06-01T17:35:48.477 に答える