I have a managed object that calls a COM server to allocate some memory. The managed object must call the COM server again to free that memory before the managed object goes away to avoid a memory leak. This object implements IDisposable
to help ensure that the correct memory-releasing COM call is made.
In the event that the Dispose
method is not called, I would like the object's finalizer to free the memory. The trouble is, the rules of finalization is that you must not access any reference because you don't know what other objects have already been GC'd and/or finalized before you. This leaves the only touchable object state to be fields (handles being the most common).
But calling a COM server involves going through an runtime callable wrapper (RCW) in order to free the memory that I have a cookie to stored in a field. Is that RCW safe to call from a finalizer (is it guaranteed to have not been GC'd or finalized at this point)?
For those of you not familiar with finalization, although the finalizer thread runs in the background of a managed appdomain while its running, at for those cases touching references would theoretically be OK, finalization also happens at appdomain shutdown, and in any order -- not just in reference relationship order. This limits what you can assume is safe to touch from your finalizer. Any reference to a managed object might be "bad" (collected memory) even though the reference is non-null.
Update: I just tried it and got this:
An unhandled exception of type 'System.Runtime.InteropServices.InvalidComObjectException' occurred in myassembly.dll
Additional information: COM object that has been separated from its underlying RCW cannot be used.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…