我有几个用于与 c++ dll 通信的非托管内存结构。每个这样的结构都必须手动释放,所以我将它包装在MyUnmanagedStructure
which implementsIDisposable
中。
我总是需要可变数量的这些结构,所以我有一个MyUnmanagedStructureCollection
也实现 IDisposable 的集合。
(请参阅下面的最小示例代码)
只要我的图书馆的用户总是调用 Dispose() 或包装集合using() {}
没有问题,但我不能保证。即使用户不手动处理集合,我也不想泄漏内存。
当MyUnmanagedStructureCollection.Dispose()
垃圾收集通过终结器调用该方法时,据我所知,我不能确定我private List<MyUnmanagedStructure>
的垃圾还没有被垃圾收集,那么在这种情况下如何处理每个结构?
在我的最终代码中,我是否应该尝试遍历列表,希望它还没有被垃圾收集?
在 try/catch 块中执行此操作并捕获 ObjectDisposedException 是否是一种好习惯?
或者我应该让每个非托管结构“自生自灭”,依靠各个终结器,而在我的集合的终结器中什么都不做?
public class MyUnmanagedStructureCollection : IDisposable
{
private List<MyUnmanagedStructure> structures;
private bool disposed = false;
#region standard IDIsposable pattern
public ~MyUnmanagedStructureCollection()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose unmanaged resources
// Should not access managed resources,
// the garbage collection may have claimed them already!
// PROBLEM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// this.structures is a List<MyUnmanagedStructure>; so is a managed resource!!!
foreach (var structure in this.structures)
structure.Dispose(disposing)
this.removeAllMemoryPressure();
if (disposing)
{
// Dispose managed resources.
this.structures.Clear();
this.structures = null;
}
}
disposed = true;
}
}
public class MyUnmanagedBuffer : IDisposable
{
...
}