Share via


System.Runtime.InteropServices。セーフHandle クラス

この記事では、この API のリファレンス ドキュメントへの補足的な解説を提供します。

このクラスは SafeHandle ハンドル リソースの重大な最終処理を提供し、ハンドルがガベージ コレクションによって途中で回収されるのを防ぎ、意図しないアンマネージ オブジェクトを参照するためにオペレーティング システムによってリサイクルされるのを防ぎます。

セーフHandle の理由

メソッドをObject.Finalizeオーバーライドすると、オブジェクトがガベージ コレクションされるときにアンマネージ リソースをクリーンに追加できますが、状況によっては、プラットフォーム呼び出し呼び出し内でメソッドを実行しているときに、ガベージ コレクションによってファイナライズ可能なオブジェクトを再利用できます。 ファイナライザーは、そのプラットフォーム呼び出しに渡されたハンドルを解放すると、破損を処理する可能性があります。 また、ファイルの読み取り中など、プラットフォーム呼び出しの呼び出し中にメソッドがブロックされている間にハンドルを再利用することもできます。

さらに重要なことに、Windows はハンドルを積極的にリサイクルするため、ハンドルをリサイクルし、機密データを含む可能性のある別のリソースを指す可能性があります。 これはリサイクル攻撃と呼ばれ、データが破損し、セキュリティ上の脅威になる可能性があります。

セーフHandle の機能

このクラスは SafeHandle 、これらのオブジェクトの有効期間に関するいくつかの問題を簡略化し、オペレーティング システム リソースがリークされないようにプラットフォーム呼び出しと統合されています。 このクラスは SafeHandle 、中断することなくハンドルを割り当てて解放することで、オブジェクトの有効期間の問題を解決します。 これには、プラットフォーム呼び出し呼び出しが破損した状態であると見なされた場合でも、ハンドルが閉じられ、予期しない AppDomain アンロード中に実行されることが保証される重要なファイナライザーが含まれています。

からCriticalFinalizerObject継承されるためSafeHandle、クリティカルでないファイナライザーはすべて、クリティカルファイナライザーの前に呼び出されます。 ファイナライザーは、同じガベージ コレクション パス中に存在しなくなったオブジェクトに対して呼び出されます。 たとえば、オブジェクトは FileStream 通常のファイナライザーを実行して、ハンドルがリークまたはリサイクルされるリスクなしに、既存のバッファリングされたデータをフラッシュできます。 クリティカルファイナライザーと非クリティカル ファイナライザーの間のこの非常に弱い順序は、一般的な使用を目的としたものではありません。 主に、これらのライブラリがセマンティクスを変更せずに使用 SafeHandle できるようにすることで、既存のライブラリの移行を支援するために存在します。 さらに、重要なファイナライザーと、メソッドなど SafeHandle.ReleaseHandle() 、呼び出すあらゆるものが、制約付きの実行領域に存在する必要があります。 これにより、ファイナライザーの呼び出しグラフ内で記述できるコードに制約が課されます。

プラットフォーム呼び出し操作では、a によって SafeHandle カプセル化されたハンドルの参照カウントが自動的にインクリメントされ、完了時にデクリメントされます。 これにより、ハンドルが予期せずリサイクルされたり閉じたりすることがなくなります。

クラス コンストラクターの引数に値を指定することで、オブジェクトを SafeHandle 構築するときに、基になるハンドルの ownsHandle 所有権を SafeHandle 指定できます。 これにより、オブジェクトが破棄された後に SafeHandle オブジェクトがハンドルを解放するかどうかを制御します。 これは、固有の有効期間要件を持つハンドルや、他のユーザーによって有効期間が制御されるハンドルを使用する場合に便利です。

セーフHandle から派生したクラス

SafeHandle は、オペレーティング システム ハンドルの抽象ラッパー クラスです。 このクラスからの派生は困難です。 代わりに、次のセーフ ハンドルを提供する Microsoft.Win32.SafeHandles 名前空間の派生クラスを使用してください。