20

管理対象リソースと非管理対象リソースについては、多くの質問があります。私は2つの基本的な定義を理解しています。ただし、リソースまたはオブジェクトがいつ管理されているか、または管理されていないかを知るのに苦労しています。

管理されていないリソースについて考えるとき、ピンボークやリソースのマーシャリングなど、.NETの直接の一部ではないネイティブコードを考える傾向があります。私は通常、ファイルハンドルやネットワーク接続など、HWを使用するものにインターフェイスするためのリソースも管理されていないと思います。

などのネイティブのアンマネージリソースをラップする.NETオブジェクトについてはどうでしょうかFileStream

管理されていないリソースを使用するFileStream必要がありますが、パターンを実装する場合、IDisposableこれを管理されたリソースまたは管理されていないリソースと見なす必要がありますか?

私はこれまで、オブジェクトが実装されていれば、IDisposableそれが管理されていると想定してきました。管理されていないリソースとして処理する必要があることをどのように知ることIntPtrができますか?

4

3 に答える 3

15

管理されていないリソースを使用するFileStream必要がありますが、IDisposableパターンを実装する場合、これを管理されたリソースまたは管理されていないリソースと見なす必要がありますか?

FileStreamは管理対象リソースです。

管理対象リソースは、管理対象外のリソースを含む(および管理する必要がある)クラスです。通常、実際のリソースは数層下にあります。

私はこれまで、オブジェクトが実装されていれば、IDisposableそれが管理されていると想定してきました。

正しい。

IntPtrを管理されていないリソースとして処理する必要があることをどうやって知ることができますか?

値を取得したAPIのドキュメントから。ただし、実際には、ほとんどのプログラマーが管理されていないリソースを直接処理することはないことに注意してください。また、必要な場合は、SafeHandleクラスを使用して、管理されていないリソースを管理されたリソースに変換します。

于 2012-12-09T10:53:49.700 に答える
10

これは非常に簡単で、管理されていないリソースを誤って割り当てることはありません。それを割り当てるにはピンボーク呼び出しが必要です、あなたはそれについて知っているでしょう。「オブジェクト」という用語はオーバーロードされていますが、管理されていないオブジェクトなどはなく、.NETプログラム内のすべてのオブジェクトが管理されています。C++などのオブジェクトの作成をサポートする別の言語で記述されたコードと相互運用できます。ただし、このようなオブジェクトを直接使用することはできません。C++/CLIラッパーが必要です。これにより、IDisposableを実装するマネージドクラスになります。

十分に文書化されていないライブラリを使用している場合は、IntPtrを取り戻すときに注意を払ってください。これは、アンマネージメモリへのポインタまたはオペレーティングシステムハンドルのいずれかで、アンマネージ割り当てが関係していることを示す非常に強力な兆候です。そのライブラリは、それ以外の方法で自動的に管理されない場合は、それを解放する方法も提供するはずです。図書館の適切な取り扱い方法がわからない場合は、図書館の所有者に連絡してください。

すべての一般的なオペレーティングシステムリソースの周りにマネージラッパークラスを提供することがMicrosoftの仕事でした。FileStream、Socketなどのように。これらのクラスは、ほとんどの場合IDisposableを実装します。このようなクラスオブジェクトを独自のクラスに格納するときにコードで行う必要があるのは、IDisposableを自分で実装することだけです。そのため、これらのオブジェクトでDispose()メソッドを呼び出します。または、メソッドでローカル変数として使用する場合は、usingステートメントを使用します。

于 2012-12-09T15:22:46.757 に答える
1

このコンテキストでの「リソース」は、「オブジェクトが他のすべての人に損害を与えるために、追って通知があるまで、オブジェクトが他の何かに代わって実行するように要求したもの」を意味すると考えると最も役立ちます。オブジェクトを放棄すると、ガベージコレクターがオブジェクトに放棄を通知し、オブジェクトがその代わりに動作していたものにそれを停止するように指示する場合、オブジェクトは「管理対象リソース」を構成します。「非管理対象リソース」とは、管理対象リソース内にカプセル化されていないリソースです。

一部のオブジェクトがアンマネージメモリにハンドルを割り当てると、メモリマネージャにメモリの一部の領域の排他的使用を許可するように要求し、メモリマネージャに通知するFooまで、他の方法でそれを使用する可能性のある他のコードが使用できないようにします。Fooメモリは不要になったため、他の目的で使用できるようにする必要があります。ハンドルをアンマネージリソースにするのは、APIを介して受信されたという事実ではなく、それへの意図的な参照がすべて放棄されたとしても、メモリマネージャーは、メモリの排他的使用をオブジェクトに永久に許可し続けるという事実です。もはやそれを必要とします(そしておそらくもはや存在しません)。

APIハンドルは最も一般的な種類の管理されていないリソースですが、他にも無数の種類があります。モニターのロックやイベントなどは、完全に.netのマネージコードの世界に存在しますが、ロックを取得してコードの待機中に放棄すると、そのコードが永久に待機する可能性があり、短命であるため、アンマネージリソースを表すことができます。存続期間のオブジェクトからイベントをサブスクライブし、放棄される前にサブスクライブ解除に失敗すると、存続期間の長いオブジェクトがイベント参照を無期限に持ち越し続ける可能性があります(1つのサブスクライバーのみが放棄された場合の小さな負担ですが、無制限の負担無制限の数のサブスクライバーが作成され、放棄された場合)。

補遺 ガベージコレクタの基本的な前提は、オブジェクトXがオブジェクトYへの参照を保持している場合、XがYに「関心がある」ためです。ただし、状況によっては、XがYに参照を保持させたいため、参照が保持される場合があります。 Yがどちらの方法でも「気にしない」としても、それに。このような状況は、通知イベントハンドラーで頻繁に発生します。オブジェクトYは、オブジェクトXに何かが発生するたびに通知を受ける必要がある場合があります。Xは、そのような通知を実行できるようにYへの参照を保持する必要がありますが、X自体は通知を気にしません。一部のルート化されたオブジェクトがYがそれらを受信することを気にする可能性があるという推定のために、それらを実行するだけです。

場合によっては、「弱いイベントパターン」と呼ばれるものを使用することが可能です。残念ながら、.netには多くの弱いイベントパターンがありますが、適切なWeakDelegateタイプがないため、それらすべてに癖と制限があります。さらに、弱いイベントは役に立ちますが、万能薬ではありません。たとえば、Y寿命の長いオブジェクトXに何かが発生したときに通知するように要求したとします。既存の参照Yは、そのXような通知に使用するものだけでYあり、そのような通知で行うのは、あるオブジェクトのプロパティをインクリメントすることだけZです。そのプロパティを設定すると、外部では何も変更されませんZ。そのシナリオでは、オブジェクトZが宇宙でオブジェクトを「気にする」唯一のものであるとしてもYZは何も参照しYないため、ガベージコレクターはYの存続期間をの存続期間に結び付ける方法がありませんZ。aXがに強い言及を持っている場合Y、後者は誰もそれに興味を持っていなくても生き続けます。X弱参照しかない場合は、興味がYあってもガベージコレクションされる可能性があります。ガベージコレクターが関心のZあるものを自動的に推測できるメカニズムはありません。ZY

于 2012-12-10T21:36:08.290 に答える