2010-07-11 18 views
7

Como dice el sujeto, escribí una clase C#, digamos Prueba, luego la compilé como una DLL y la expuse a Excel como un servidor de automatización COM. Ahora, puede llamar a los métodos de esa clase en fórmulas de Excel directamente o a través de una función de VBA que los llame bajo el capó. Lo que sucede en el segundo caso es relativamente transparente (¡escribiste el código!), Mientras que en el primer caso asumo que una instancia de Prueba se instancia y se usa de forma transparente (tiene que ser porque los métodos expuestos no son y, por lo que he leído - no puede ser estático) pero exactamente cuándo y cómo no está claro. Por lo tanto, mi pregunta es: ¿cuál es el ciclo de vida preciso de un servidor de automatización llamado en este contexto y dónde está eso documentado?Ciclo de vida del servidor de automatización .NET llamado desde Excel a través de COM

Una pregunta subsidiaria es si hay una manera de hacer que tanto las llamadas directas en las fórmulas y las llamadas a través de VBA utilicen una sola instancia única de Prueba. Creo que ya sé cómo hacer que todos los procedimientos de VBA utilicen una sola instancia de prueba, pero aun así se crea una segunda cada vez que se llama directamente a un método de prueba en una fórmula.

Por último, si esa clase de prueba contiene recursos en el nivel de clase (es decir, recursos estáticos), ¿cuándo y cómo debe deshacerse de ellos? De nuevo, eso plantea la pregunta de cuándo exactamente las clases Test son creadas y destruidas por .NET/COM Interop.

Precisión: el servicio es una DLL, no una aplicación, y Excel debe ser el único que lo usa, aunque puede haber más de una copia abierta de la hoja de cálculo. Se trata de Excel 2007.

Respuesta

1

"Excel debe ser la única cosa usarlo":

I found out the hard way que, posiblemente, la única manera de lograr esta restricción aplicación es hacker o cryptic. AFAIK: mantenga una lista codificada o externa de listas blancas/negras de la aplicación de llamada referenciadas por su biblioteca, con una búsqueda realizada en cada carga de la biblioteca. Por naturaleza, las clases COM están expuestas al mundo entero ... literally.

"si hay una forma de hacer ambas llamadas directas en fórmulas y llamadas a través de VBA, use una única instancia única de Prueba?"

Tendrá que tratarlo como un singleton, ya sea tratando muy duro de usar continuamente solo una instancia, o realizar una función de "envoltura simple" que contenga una variable estática que contenga la referencia del objeto en su código VBA.

"si esa clase de prueba contiene recursos a nivel de clase (es decir, los recursos estáticos), cuándo y cómo se debe disponer de ellos?":

Están (por lo general) limpian automáticamente al cierre de la aplicación tiempo, o cuando la aplicación llama al COM object's 'finalize' method (if applicable to the internal workings of the COM class's library), o cuando de lo contrario la referencia del objeto cuenta drops to 0 (if applicable to the internal workings of the COM class's library).

Creo que una pregunta que podría proporcionar una mejor idea es: "¿Cómo funciona la clase COM particular que estoy utilizando maneja su propia vida útil?" A veces, los objetos COM son perpetuos, incluso más allá del final de un procedimiento dentro de su aplicación de llamada. Dependiendo del diseño de la clase COM, se puede hacer que el objeto permanezca activo, independientemente de si queda algún objeto de referencia restante dentro de la aplicación llamante. Algunas veces se le requerirá destruir explícitamente la referencia del objeto (usando los métodos 'borrar' de VBA) o de lo contrario el objeto podría persistir (tal como lo diseñaron los diseñadores de esa clase COM en particular) siempre que lo haga la aplicación llamante. Esto es dolorosamente evidente por la persistencia de los objetos ActiveX desde el sitio web al sitio web, y una de las razones principales por las que al navegar por la red, es mejor "no confiar en nadie".Lo que es peor es que si un objeto en sí mismo perpetua hace referencia a otros objetos y recursos internos.

realmente obtener una manija en la vida útil de la clase, habría que estudiar la documentación proporcionada por los autores de clase COM. En este caso, tendrá que idear una manera de dentro de la biblioteca de clases COM para hacer cumplir o proporcionar métodos de acceso externo para hacer cumplir los estándares de vida útil (aplicación IDisposable, que ofrecen su propio método público Dispose(), etc).

Un enlace de referencia a la DLL sin duda permanecerá activo durante todo el tiempo de vida de la aplicación de llamada, de haber nacido en el momento en que incluso intentó crear el primer objeto. AFAIK, no hay nada que puedas hacer al respecto. Esto es evidente con sólo el seguimiento de información propiedad de las aplicaciones DLL utilizando algún sistema de partidos tercera solicitud de información. Esto tiene sentido, ya que ahorra recursos de carga y descarga de la DLL cada vez que lo necesite.

Cuestiones relacionadas