35 votes

Pourquoi utiliser FinalReleaseComObject au lieu de ReleaseComObject?

Je sais que la différence fondamentale qu' ReleaseComObject seulement réduit le compteur de un et FinalReleaseComObject , elle diminue à zéro.

Donc ce que j'ai l'habitude de l'entendre, appelez FinalReleaseComObject parce que vous êtes sûr que l'objet COM est vraiment libéré.

Mais cela me fait demander, il est un point sur ce compteur de droite? N'êtes-vous pas briser ce mécanisme si vous appelez toujours FinalReleaseComObject. Si le compteur n'est pas un avant vous appelez ReleaseComObject,, il est probablement pas une raison pour cela?

Ce pourrait-il provoquer à être plus élevé que celui où il ne devrait pas être?

Merci à l'avance.

PS: Mon COM de l'expérience consiste seulement à l'aide d'Excel Interop. Vous ne savez pas si cette question est locale pour ce domaine (c'est à dire en dehors de l'Interopérabilité, FinalReleaseComObject n'est pas souvent utilisé).

Mise à jour 1

L' article de Dan mentionné parle à l'aide de ReleaseComObject lorsque vous avez terminé. Ce que je comprends de l' article, c'est la façon normale. Je pense que si vous faites cela régulièrement, il devrait fonctionner correctement. Dans un commentaire à l' article , l'auteur propose à quelqu'un d'appeler ReleaseComObject dans une boucle jusqu'à ce qu'il est vraiment sorti (l' article est à partir de 2006, c'est donc analogues à l'appel de FinalReleaseComObject). Mais il affirme également que cela pourrait être dangereux.

Si vous voulez vraiment le BRF à appeler Release() à un point particulier dans le code, vous pouvez appeler ReleaseComObject() dans une boucle jusqu'à ce que la valeur de retour atteint zéro. Cela devrait assurer le BRF va appeler Release(). Toutefois, si vous le faites, être averti, quand les autres références essaie d'utiliser le BRF, il va provoquer une exception."

Cela me mène à croire que c'est vraiment pas une bonne idée de toujours faire appel à FinalReleaseComObject, comme vous pouvez causer des exceptions ailleurs. Comme je le vois maintenant, vous devez seulement appeler cette fonction si vous êtes absolument sûr que vous le pouvez.

Encore, j'ai peu d'expérience en la matière. Je ne sais pas comment je peux être sûr. Si le compteur est augmenté quand il ne devrait pas être, n'est-il pas mieux pour résoudre ce problème? Si oui, alors je dirais FinalReleaseComObject est plus un hack qu'une meilleure pratique.

38voto

Dan Blanchard Points 2757

Certains préambule...

Runtime Callable Wrapper (RCW) seuls les appels IUnknown.AddRef une fois sur le non géré COM interface qu'il encapsule. Cependant, un RCW maintient également séparé de compter le nombre de références gérées sont là pour le BRF lui-même. C'est ce nombre de références gérées qui est décrémenté par un appel à Maréchal.ReleaseComObject. Lorsque le nombre de références gérées atteint zéro, le BRF appels IUnknown.Relâchez une fois sur le non géré interface COM.

Maréchal.FinalReleaseComObject prend la gestion de compte de référence à zéro avec un seul appel, et donc invoque le enveloppés non géré IUnknown.Méthode Release immédiatement (en supposant que la gestion de compte de référence n'était pas déjà de zéro).

Alors, pourquoi avez à la fois le Maréchal.ReleaseComObject et le Maréchal.FinalReleaseComObject? L'Appel De Maréchal.FinalReleaseComObject simplement d'éviter d'avoir à écrire une boucle qui appelle le Maréchal.ReleaseComObject à plusieurs reprises jusqu'à ce qu'elle retourne 0 si vous souhaitez indiquer que vous l'avez vraiment fini à l'aide d'un objet COM maintenant.

Pourquoi utiliser le Maréchal.ReleaseComObject ou Maréchal.FinalReleaseComObject? Il y a deux raisons pour lesquelles je suis au courant de:

Le premier est de s'assurer que les ressources non managées (comme les handles de fichiers, la mémoire, etc.) utilisé par le enveloppés d'objets COM sont libérées dès que possible à la suite du résultat de l'appel à la non géré IUnknown.Méthode Release ().

La deuxième est de veiller à ce que le thread appelant la non géré IUnknown.Méthode Release() est sous votre contrôle, et non pas le finaliseur fil.

Sans les appels à l'une de ces Maréchal des méthodes, de la PONDÉRATION du finalizer fera finalement appel non managé IUnknown.Méthode Release() peu de temps après le BRF a été nettoyée.

Pour des détails, voir l'Équipe Visual C++ entrée de blog de Mélange déterministes et non-déterministes de nettoyage

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X