【发布时间】:2010-04-29 21:41:41
【问题描述】:
这个问题是关于处理非托管资源(COM 互操作)并确保不会有任何资源泄漏。对于我是否似乎以正确的方式做事的反馈,我将不胜感激。
背景:
假设我有两个类:
一个类
LimitedComResource,它是一个 COM 对象的包装器(通过某些 API 接收)。这些 COM 对象的数量有限,因此我的类实现了IDisposable接口,该接口将负责在不再需要时释放 COM 对象。临时创建另一种类型的对象
ManagedObject以在LimitedComResource上执行一些工作。他们不是IDisposable。
用图表总结以上内容,我的类可能如下所示:
+---------------+ +--------------------+
| ManagedObject | <>------> | LimitedComResource |
+---------------+ +--------------------+
|
o IDisposable
(稍后我将提供这两个类的示例代码。)
问题:
由于我的临时 ManagedObject 对象不是一次性的,我显然无法控制它们会存在多长时间。然而,与此同时,我可能有Disposed LimitedComObject ManagedObject 所指的LimitedComObject。 如何确保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!
}
}
【问题讨论】:
标签: .net com-interop idisposable weak-references object-lifetime