2010-02-14 179 views
33

Tengo un componente COM que llamo desde algunos C# dll.El objeto COM que se ha separado de su RCW subyacente no se puede usar

También tengo una aplicación de winforms que usa ese .dll.

Al cerrar la aplicación que consiguen esta excepción:

objeto COM que se ha separado de su RCW subyacente no puede ser utilizado .

El seguimiento de pila muestra que esta excepción proviene de un destructor en el .dll. Implementé este destructor para llamar a algún método de limpieza en el COM.

¿Por qué sucede esto? ¿Cómo es mejor resolverlo?

+5

leyeron: http://jake.ginnivan.net/vsto-com-interop –

+0

duplicado posible de [objeto COM que se ha separado de su RCW subyacente no puede ser utilizado] (http://stackoverflow.com/questions/1567017/com-object-that-has-been-separated-from-its-underlying-rcw-can-be-used) – bluish

Respuesta

30

El problema se describe aquí:

Is it safe to call an RCW from a finalizer?

y aquí:

Release Excel Object In My Destructor

El problema es que no sólo es el tiempo en cuanto a cuando estos objetos son a ser basura recolectada incierta, pero el orden en que se llaman los finalizadores también es indeterminado istico. En este caso, un Contenedor invocable Runtime también tiene un finalizador que llama al Marshal.FinalReleaseComObject en sí mismo, que tiene el resultado de disminuyendo el recuento de referencias en el lado COM de la valla para que este objeto COM pueda ser liberado. Pero dado que el orden en el que se llaman los finalizadores es incierto, es muy posible que los finalizadores para los objetos COM a los que hace referencia su objeto activarán antes del finalizador para su objeto. Por lo tanto, el código dentro del finalizador podría funcionar a veces, pero la mayoría de las veces los contenedores invocables en tiempo de ejecución que sus referencias de objeto tendrán ya tuvieron sus finalizadores llamados y el objeto COM subyacente se habrá liberado su finalizador consigue ejecutar su código.

+73

¡No seguí nada! : x – nawfal

+7

Está bastante claro: el contenedor COM alrededor del objeto que instanciaste podría limpiarse antes de que puedas limpiarlo tú mismo. Traducción: Si su Dispose() intenta llamar a Marshal.ReleaseCOMObject (x) cuando esa x subyacente ya ha salido del alcance, su Dispose() fallará. Tengo que verificar ese alcance/ciclo de vida. Gracias por los buenos enlaces, @Ran. – JMD

+0

Gracias por su comentario JMD, de hecho lo aclaró para mí – Alex

Cuestiones relacionadas