I have a class which provides an adapter to a COM object. Here's a much simplified version of it:
public class DocumentWrapper
{
private COMDocument doc;
public DocumentWrapper(COMDocument doc)
{
this.doc = doc;
this.doc.OnClose += OnClose;
}
private void OnClose()
{
this.doc.OnClose -= OnClose;
this.doc = null;
}
public bool IsAlive { get { return this.doc != null; } }
}
The problem is that the OnClose event handler is keeping both objects alive. Both objects should have the same lifetime, so when one goes away the other should too, i.e. nobody is keeping one alive and expecting the other to go away.
I did experimenting with weak references:
COMDocument com = CreateComDocument();
var doc = new DocWrapper(com);
WeakReference weak1 = new WeakReference(com);
WeakReference weak2 = new WeakReference(doc);
GC.Collect(2, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
GC.Collect(2, GCCollectionMode.Forced);
if (weak1.Target != null)
Console.WriteLine("COM was not collected");
if (weak2.Target != null)
Console.WriteLine("Wrapper was not collected");
If OnClose is not registered, both objects get collected. If OnClose is registered, neither object gets collected. How do I ensure the pair of objects is collectible without losing the event?