我有一些非託管內存結構用於與C++ dll進行通信。 每個這樣的結構都必須手動釋放,所以我把它包裝在MyUnmanagedStructure
中,它實現了IDisposable
。在終結器中處理一個IDisposables列表
我總是需要這些結構的可變數量在一起,所以我有一個集合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
{
...
}
當它仍然從您的對象引用時,如何收集列表?只是收集中的對象可能已經完成(但未收集)。 – CodesInChaos
那麼,我的對象和對象內的列表將被收集在一起,並且據我瞭解,GC並不能保證它以何種順序銷燬它們。我可能是錯誤的,雖然 – HugoRune
GC並不保證*定稿*的順序。它保證從終結器到達的任何對象尚未被收集。 – CodesInChaos