2

主な違いはどこですか?SafeBuffer が SafeHandleZeroOrMinusOneIsInvalid を派生していることは知っていますが、他に何がありますか?

いつどちらを使用する必要がありますか?

(CPU または GPU のいずれかで) ネイティブ配列を割り当てて制御する必要があります。マネージ カスタム配列に SafeBuffer または SafeHandleZeroOrMinusOneIsInvalid を実装する必要がありますか? SafeBuffer という名前の方が理にかなっているように聞こえますが、なぜそれを実装し、使用する前に Initialize を呼び出さなければならないのでしょうか?

4

1 に答える 1

3

主な違いはどこですか?

どこにいても、彼らには何の共通点もありません。SaveBuffer は SafeHandle を継承して、SafeHandle が提供する重要なファイナライザーを利用します。これにより、通常はファイナライザーの実行を妨げるプログラムのハードクラッシュなど、最も悲惨な状況でもバッファーが解放されます。

SaveBuffer は、オペレーティング システムの呼び出しによって取得されたアンマネージ メモリのラッパーです。ReleaseHandle() メソッドという、まだ抽象的なメソッドが1 つだけあります。winapi 呼び出しごとに、メモリに関連付けられているハンドルを解放する方法が異なるためです。たとえば、LocalAlloc() には LocalFree() が必要です。SysAllocString() には SysFreeString() が必要です。MapViewOfFile() には UnmapViewOfFile() などが必要です。

安全なハンドル保証を利用するために、SaveBuffer() から独自のクラスを派生させることができます。アンマネージ ポインターを受け取り、SetHandle() を呼び出すコンストラクターが必要です。また、メモリを再度解放するには ReleaseHandle() を実装する必要があります。

実際にこれを行うべきかどうかは非常に疑わしいです。ReleaseHandle() メソッドは、重要なファイナライザーによって呼び出されます。このような方法では実行できないことが多数あります。重要なファイナライザーの要件は、ファイナライザー自体が破損を引き起こし、他の重要なファイナライザーの実行を妨げることを確実にするために厳しいものです。CLR は、たとえば、例外が生成されないようにするモードで実行されます。これは、アップタイムを強力に保証するカスタム CLR ホスティング環境でのみ問題になります。SQL Server はその主要な例です。オペレーティング システムの呼び出しを行う場合は、それを使用しても問題ありません。これは、堅実なコードです。GPUバッファ、まあ、それほど多くはありません。独自のファイナライザーを使用して独自のラッパーを作成するだけで、先に進む可能性があります。君は'リリース呼び出しが失敗したときの事故のデバッグが容易になります。

于 2013-11-14T10:41:07.773 に答える