2010-11-13 3 views
3

J'instancie un objet COM à partir d'un script VBA dans Excel comme défini dans une DLL C#. L'instanciation C# de classe I a un finaliseur qui effectue la récupération de place, notamment les autres objets MS Office auxquels il fait référence, que je devrais voir apparaître et disparaître dans le gestionnaire de tâches. En fait, les tests unitaires démontrent qu'un processus Office apparaît lorsque la DLL est appelée, et disparaît quand il est terminé. Lorsque la DLL est appelée depuis le VBA, j'ai remarqué que les processus restent ouverts après la fin de la fonction VBA, c'est-à-dire que l'objet n'est pas nettoyé après l'appel, ce qui me porte à croire que VBA ne libère pas l'objet COM .COM Objets de nettoyage

Ma fonction ressemble à ceci:

Function Raz(inp As String) 
Dim o: Set o = CreateObject("foo.bar") 
o.InputFields.FirstInput = inp 
o.Update 
Raz = o.OutputFields.FirstOutput 
End Function 

J'ai ajouté la ligne suivante à la fin de la fonction afin de résoudre le problème:

set o = Nothing 

Cependant, les ressources dans mon Le processus COM reste après l'exécution et l'achèvement de mon script VBA. Comment puis-je ramasser mes objets COM de VBA sans créer manuellement un appel d'élimination?

Répondre

1

Dans VBA la commande pour libérer un objet est

Set o = Nothing 
+0

alors j'ai essayé cela, et le finaliseur n'est toujours pas appelé. J'ai fini par implémenter IDisposable et à disposer manuellement des ressources, en combinaison avec l'ensemble o = Nothing line ... Je ne sais pas si tout se libère mais au moins la disposition libère les grosses choses. – tbischel

+0

Pourriez-vous donner plus d'explications sur la façon dont vous avez implémenté IDisposable, s'il vous plaît? J'ai le même problème avec un serveur Visual Foxpro 9 COM que j'ai écrit. Merci. – Caltor

+0

@Caltor, vous devez '@ tbischel' pour attirer son attention (seul le premier @ fonctionne, vous devez donc le faire vous-même). –

4

COM gardera les processus en mémoire pendant un certain temps après la dernière référence est allé, juste au cas où vous voulez créer un autre objet nécessitant bientôt le même processus ensuite.

La théorie est que la création de processus est très lent et coûteux, et vous pourriez par inadvertance écrire une boucle ou quelque chose qui fait cela:

While 1=1 

     Set a = CreateObject(...) 
     ' Later 
     Set a = Nothing 

Wend 

Vous ne voudriez pas raclée Windows dans le meurtre et le lancement de processus sans fin dans la boucle.

Finalement, ils partent.

1

Vous avez un référence faible à l'objet créé, Raz valeur de retour de la fonction, qui maintient l'instance d'objet.

o variable est automatique et objet référencé est automatiquement réglé à rien lorsque la fonction de retour, mais vous assignez la valeur à Raz et probablement au code client de sorte que la valeur instancié n'est pas disposé sur le retour de la fonction.

De plus, si l'objet, en l'occurrence, fait référence à un contrôle utilisateur, vous ne pourrez probablement pas décharger le formulaire qui le contient.