2010-04-02 5 views
6

Hasta hace poco, creía que el tiempo de ejecución de .NET solo aumenta el recuento de referencias de los objetos COM en 1 al crear un runtime-callable wrapper, y que solo se crea uno de estos wrapper invocables en tiempo de ejecución para cualquier objeto COM dado.¿Cuándo el tiempo de ejecución de .NET contiene un recuento de referencia> 1 para objetos COM?

Si no me equivoco, lo anterior implica que Marshal.FinalReleaseComObject y Marshal.ReleaseComObject hacen lo mismo en la práctica.

Sin embargo, hoy estaba escribiendo algunas pruebas para verificar que los objetos COM salgan correctamente de mi código. Lo hago invocando el objeto supuestamente liberado y comprobando el esperado InvalidComObjectException. Resulta que hay casos en los que se lanza la excepción después de FinalReleaseComObject, pero no después de ReleaseComObject.

¿Significa esto que el tiempo de ejecución de .NET 2.0 puede contener más de una referencia a un objeto COM? Si es así, ¿cuándo hace esto?

Respuesta

5

Aquí hay un nivel adicional de indirección. Sí, el RCW mantiene un recuento de referencia único en los punteros de la interfaz COM nativa. Pero el RCW también tiene un recuento de referencias, se incrementa cada vez que se asigna un puntero de interfaz COM al RCW. Lo que puede suceder si un método COM devuelve un puntero de interfaz. El finalizador de la clase .NET contenedora correspondiente lo disminuye.

Puede modificar el recuento de referencias directamente a través de Marshal.ReleaseComObject(), que lo disminuye en uno como lo hace el finalizador, y Marshal.FinalReleaseComObject(), que lo pone a cero, garantizando que IUnknown :: Release () se llama método. Por supuesto caen en la categoría de "saber mejor lo que estás haciendo". Hacerlo mal produce el desagradable objeto "objeto COM separado de su RCW subyacente".

Cuestiones relacionadas