この質問は、管理されていないリソース(COM相互運用)を処理し、リソースリークが発生しないようにすることに関するものです。私が物事を正しい方法で行っているように見えるかどうかについてのフィードバックをいただければ幸いです。
バックグラウンド:
2つのクラスがあるとしましょう。
COMオブジェクトのラッパーであるクラス
LimitedComResource
(一部のAPIを介して受信)。これらのCOMオブジェクトの数は限られているため、私のクラスはIDisposable
、COMオブジェクトが不要になったときにCOMオブジェクトを解放する役割を担うインターフェイスを実装します。別のタイプのオブジェクトは、で
ManagedObject
いくつかの作業を実行するために一時的に作成されますLimitedComResource
。彼らはそうではありませんIDisposable
。
上記を図にまとめると、私のクラスは次のようになります。
+---------------+ +--------------------+
| ManagedObject | <>------> | LimitedComResource |
+---------------+ +--------------------+
|
o IDisposable
(これら2つのクラスのサンプルコードをすぐに提供します。)
質問:
私の一時的なManagedObject
オブジェクトは使い捨てではないので、私は明らかにそれらがどれくらいの期間存在するかを制御することはできません。しかし、その間に私はaが参照しているDispose
dを持っているかもしれません。もはやそこにないにアクセスしないようにするにはどうすればよいですか?LimitedComObject
ManagedObject
ManagedObject
LimitedComResource
+---------------+ +--------------------+
| managedObject | <>------> | (dead object) |
+---------------+ +--------------------+
私は現在、弱参照と、LimitedResource
オブジェクトがすでに破棄されているかどうかを示すフラグを組み合わせてこれを実装しています。より良い方法はありますか?
サンプルコード(私が現在持っているもの):
LimitedComResource
:
class LimitedComResource : IDisposable
{
private readonly IUnknown comObject; // <-- set in constructor
...
void Dispose(bool notFromFinalizer)
{
if (!this.isDisposed)
{
Marshal.FinalReleaseComObject(comObject);
}
this.isDisposed = true;
}
internal bool isDisposed = false;
}
ManagedObject
:
class ManagedObject
{
private readonly WeakReference limitedComResource; // <-- set in constructor
...
public void DoSomeWork()
{
if (!limitedComResource.IsAlive())
{
throw new ObjectDisposedException();
// ^^^^^^^^^^^^^^^^^^^^^^^
// is there a more suitable exception class?
}
var ur = (LimitedComResource)limitedComResource.Target;
if (ur.isDisposed)
{
throw new ObjectDisposedException();
}
... // <-- do something sensible here!
}
}