2009-05-14 10 views
0

J'ai écrit un composant COM dans C++ non géré pour permettre aux clients d'accéder à notre base de données. Lorsque vous l'utilisez à partir d'un langage non géré, les connexions à la base de données sont correctement nettoyées lorsque les objets sont hors de portée. J'ai récemment essayé de l'utiliser à partir de VB.NET et découvert que les objets COM ne sont pas détruits. La diffusion des appels vers System.Runtime.InteropServices.Marshal.ReleaseComObject résout le problème, mais j'aimerais trouver une solution plus simple et plus sûre puisque cet objet COM est conçu pour être utilisé par le client.Comment implémenter Dispose dans un objet COM

Il semble que la bonne solution est d'avoir les objets gérés mettre en œuvre IDisposeable de sorte que le using peut être utilisé, appeler automatiquement Éliminez lorsque l'objet est plus nécessaire.

Comment procéder pour implémenter IDisposeable pour un sous-ensemble de mes objets? Plusieurs des objets qui doivent être éliminés ne sont pas co-créables mais sont renvoyés par d'autres fonctions.

+0

peut-être ma réponse à cette question (http://stackoverflow.com/questions/158706/how-to-properly-clean-up-excel-interop -objects-in-c/158752 # 158752) aide avec votre cas spécifique. – VVS

Répondre

2

La folie est comme ça. Il vaudra mieux encapsuler vos objets COM dans des wrappers sécurisés de type .NET qui implémentent IDisposable (si vous préférez), ou utilisez les méthodes normales de ramasse-miettes .Net pour se nettoyer.

+0

Existe-t-il un meilleur moyen de s'assurer que les connexions à la base de données sont fermées autrement que d'utiliser IDisposable? Je voudrais vraiment m'assurer que tous les objets COM sont nettoyés car actuellement il y a un crash à la sortie lorsque mes caches dans le composant COM sont détruits dans DllMain. Si les objets COM étaient libérés, les caches seraient vides. –

2

Vous pouvez aller avec les wrappers .NET comme 1800 INFORMATION suggère, rappelez-vous donc de toujours les utiliser avec une déclaration en utilisant comme vous avez dit:

using(var connection = GetDisposableConnection()) 
{ 
    //do stuff 
} 

Si cela ne fonctionne pas parce que quelque chose était pas publié correctement, vous pouvez insérer ces lignes lors de l'arrêt:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
+0

Merci pour la pointe de l'appel WaitForPendingFinalizers, je ne l'avais pas rencontré auparavant. –

+0

Pas de problème - heureux d'avoir aidé. – Ant

Questions connexes