c# .net outlook add-in pia

c# - Liberar componentes COM



.net outlook (8)

Aquí hay algunas buenas prácticas que usan una envoltura administrada ... vale la pena revisar ...

¿Es realmente necesario liberar los componentes COM desde Office PIA, cuando ya no los necesita invocándolos a Marshal.ReleaseComObject (...)?

Encontré varios y contradictorios consejos sobre este tema en la web. En mi opinión, dado que Outlook PIA siempre devuelve nuevas referencias a sus interfaces como valores devueltos por sus métodos, no es necesario liberarlo explícitamente. ¿Estoy en lo cierto?


Los PIA son envolturas de intercalación .NET. Esto significa que en el destructor del objeto (o Dispose, no recuerdo) manejará automáticamente su recuento de referencias. El truco es que algunas referencias no se liberarán hasta que se ejecute el recolector de elementos no utilizados. Depende de lo que crea el objeto COM. Por ejemplo, un objeto COM que abre cursores de base de datos mantendrá esos cursores vivos en memoria hasta que se libere el recuento de referencia en esos cursores. Con la interoperabilidad .NET / COM, las referencias no se publican hasta que se ejecuta el recolector de elementos no utilizados o se libera explícitamente la referencia utilizando Marshal.ReleaseComObject (o FinalReleaseComObject).

Personalmente, no he trabajado con los PIA de Microsoft Office, pero en la mayoría de las circunstancias, no debería tener que liberar explícitamente las referencias. Solo cuando la aplicación comienza a bloquear otros recursos o se bloquea, debe comenzar a sospechar de las referencias pendientes.

EDITAR: si se encuentra con una situación en la que necesita limpiar objetos COM / Interop, use Marshal.FinalReleaseComObject, que lleva el recuento de referencias a cero en lugar de simplemente decrementar en uno, y establezca la referencia del objeto en nulo. Puede forzar explícitamente la recolección de basura (GC.Collect) si realmente quiere estar seguro, pero tenga cuidado de hacer GC con demasiada frecuencia ya que invoca un golpe de rendimiento notable.


Tal vez sea solo mi superstición, pero decidí liberar explícitamente el PIA de Office a través de Marshal.ReleaseComObject () porque cuando mi aplicación se bloqueó, las referencias a Excel y Word permanecieron abiertas. No profundicé en el por qué (estúpidos plazos), pero liberarlos como parte del patrón de disposición de mi clase resolvió ese problema.


Hay una regla simple sobre interoperabilidad .NET / COM: en caso de duda, siempre Libere (). :-)



Con Microsoft Office, en general, necesita liberar explícitamente sus referencias, que se pueden realizar de forma segura en dos etapas:

(1) Primero libere todos los objetos menores a los que no tenga una variable de objeto con nombre mediante una llamada a GC.Collect () y luego a GC.WaitForPendingFinalizers (). (Debe llamar a esto dos veces, si los objetos involucrados pueden tener finalizadores, como cuando usa Visual Studio Tools for Office (VSTO)).

(2) Luego, libere explícitamente los objetos a los que tiene una variable nombrada mediante una llamada a Marshall.FinalReleaseComObject () en cada objeto.

Eso es. :-)

Discutí esto con más detalle en una publicación anterior , junto con un ejemplo de código.


Debe hacerlo si desea que la instancia de la aplicación de Office salga, como se describe en esta publicación .

Y es difícil acertar en todos los escenarios menos en los más simples.


Mi experiencia demuestra que debes hacerlo, de lo contrario (al menos Outlook) la aplicación puede no apagarse en absoluto.

Pero esto abre otra lata de gusanos, ya que parece que los RCW son por proceso, por lo que puede romper algún otro complemento, que tiene una referencia al mismo objeto.

He publicado una pregunta relacionada aquí , pero todavía no tengo una respuesta clara. Editaré esta publicación una vez que sepa más.