Al usar COM Interop con Office (generalmente Excel), siempre me aseguro cuidadosamente de llamar al Marshal.ReleaseComObject
en cada referencia, para evitar el problema donde Excel no abandona as described in this KB article.Cómo liberar objetos COM en Silverlight 4
¿Cómo puedo garantizar que Excel se cierra cuando uso Interop desde una aplicación OOB Silverlight (con AutomationFactory.CreateObject
)?
Silverlight no tiene un método Marshal.ReleaseComObject
e incluso llamar a GC.Collect
y GC.WaitForPendingFinalizers
no ayuda.
¿Seguro que Microsoft no ha agregado esta característica a Silverlight sin un mecanismo para liberar las referencias COM? Esto me parece ser una maravilla para la automatización de servidores COM fuera de proceso como Excel.
Un sorprendente omisión, tanto más cuanto que Pete Brown en la sección 5.5 de su libro "Silverlight 4 en Acción" va tan lejos como para decir sobre AutomationFactory.CreateObject
, que:
La intención principal de esta característica es permitir la automatización de otras aplicaciones, incluida Microsoft Office.
ACTUALIZACIÓN en respuesta a los comentarios de Hans.
No estoy seguro de que exista un problema de "asesino silencioso" en la automatización típica de las aplicaciones de Office. Un uso común podría ser algo como lo siguiente, que he visto utilizar en varias ocasiones en las aplicaciones de Windows Forms, sin llegar nunca a través de la "envenenado RCW" descrito en el artículo enlazado por Hans:
- Crear una instancia Excel.Application
- Abrir o crear un libro
- datos de escribir en el libro de
- Mostrar Excel si todo iba bien, cierre el libro y llame Application.Quit si no.
- Llame a Marshal.ReleaseComObject para liberar todas las referencias de objetos de Excel.
Si no se puede llamar a Marshal.ReleaseComObject según lo recomendado por Hans, se dejarán ejecutadas varias copias de Excel.exe, como se describe en el artículo de KB mencionado anteriormente: altamente indeseable.
ACTUALIZACIÓN 2
La muestra que estoy usando para repro esto es una muestra del código fuente para el libro de Pete Brown Silverlight 4 en la acción, hay un enlace de descarga en esta página. La solución de muestra AutomatingExcel está en Ch05.zip/5.03. Para repro:
- Asegúrese de que no hay instancias de Excel están ejecutando
- muestra Run AutomatingExcel
- libro de Excel se abre
- Cierre Excel
- Observar con el Administrador de tareas de Excel que todavía se está ejecutando.
Configurando todas las variables dinámicas a nulo y llamando a GC.Collect() parece funcionar como se indica en la respuesta de AnthonyWJones.
ACTUALIZACIÓN 2
respuesta de Otaku es lo que estaba buscando - envolviendo referencias en una instrucción using las referencias COM son puestos en libertad sin la necesidad de llamar a GC.Collect. Un poco de experimentación muestra que es más tolerante a no disponer de cada referencia individual, a diferencia de la solución estándar Marshal.ReleaseComObject
descrita en el artículo de KB mencionado anteriormente.
Sería interesante tener una opinión autorizada sobre exactamente lo que debe eliminarse para garantizar que se publiquen todas las referencias de Excel.
posible duplicado de [? Cuándo utilizar RelaseComObject vs FinalReleaseComObject] (http://stackoverflow.com/ preguntas/3937181/when-to-use-relasecomobject-vs-finalreleasecomobject) –
@Hans: Silverlight no tiene ninguno de estos métodos en la clase 'Marshal'. – AnthonyWJones
@Anthony: explica por qué ninguno de estos métodos es una buena idea. El enlace "asesino silencioso" es muy relevante. –