Ich habe ein verwaltetes Objekt, das einen COM-Server zum Reservieren von Speicherplatz aufruft. Das verwaltete Objekt muss den COM-Server erneut aufrufen, um diesen Speicher freizugeben, bevor das verwaltete Objekt entfernt wird, um einen Speicherverlust zu vermeiden. Dieses Objekt implementiert IDisposable
, um sicherzustellen, dass der korrekte speicherauslösende COM-Aufruf erfolgt.Ist es sicher, einen RCW von einem Finalizer aus aufzurufen?
Für den Fall, dass die Dispose
Methode ist nicht aufgerufen, möchte ich den Finalizer des Objekts, um den Speicher zu befreien. Das Problem ist, dass die Finalisierungsregeln darin bestehen, dass Sie nicht auf eine Referenz zugreifen dürfen, weil Sie nicht wissen, welche anderen Objekte bereits vor Ihnen abgeschlossen und/oder finalisiert wurden. Dies lässt den einzigen berührbaren Objektstatus als Felder (Griffe sind am häufigsten).
Aber das Aufrufen eines COM-Servers beinhaltet das Durchlaufen eines Runtime Callable Wrapper (RCW), um den Speicher freizugeben, in dem ein Cookie in einem Feld gespeichert ist. Kann RCW sicher von einem Finalizer aus angerufen werden (ist es garantiert, dass zu diesem Zeitpunkt noch kein GC oder finalisiert wurde)?
Für diejenigen von Ihnen nicht vertraut mit Abschluss, obwohl die Finalizerthread im Hintergrund eines verwalteten Appdomain läuft während seines Lauf, um für die Fälle, Referenzen zu berühren theoretisch wäre in Ordnung, geschieht Finalisierung auch bei Appdomain Herunterfahren und in beliebiger Reihenfolge - nicht nur in der Reihenfolge der Referenzbeziehung. Dies beschränkt das, was Sie von Ihrem Finalizer als sicher erachten können. Jeder Verweis auf ein verwaltetes Objekt ist möglicherweise "fehlerhaft" (gesammelter Speicher), obwohl der Verweis nicht null ist.
aktualisieren: Ich habe versucht, es einfach und bekam dies:
Eine nicht behandelte Ausnahme des Typs 'System.Runtime.InteropServices.InvalidComObjectException' in MyAssembly.dll
Zusätzliche Informationen aufgetreten: COM-Objekt das von seinem zugrundeliegenden RCW getrennt wurde, kann nicht verwendet werden.
Eine Methode auf dem COM-Server (warum sollte jemand Dispose auf einem RCW selbst nennen? Ich wäre überrascht, wenn das überhaupt möglich wäre). –