web-dev-qa-db-fra.com

L'objet COM qui a été séparé de son RCW sous-jacent ne peut pas être utilisé

J'ai un composant COM que j'appelle à partir d'une DLL c #.

J'ai également une application Winforms qui utilise ce fichier .dll.

Lorsque je ferme l'application, j'obtiens cette exception:

L'objet COM qui a été séparé de son RCW sous-jacent ne peut pas être utilisé.

La trace de pile montre que cette exception provient d'un destructeur dans le .dll. J'ai implémenté ce destructeur pour appeler une méthode de nettoyage dans le COM.

Pourquoi cela arrive-t-il? Comment est-il préférable de le résoudre?

44
Yaron Naveh

Le problème est décrit ici:

Est-il sûr d'appeler un RCW depuis un finaliseur?

et ici:

Libérer l'objet Excel dans mon destructeur

Le problème est que non seulement le moment où ces objets doivent être récupérés est incertain, mais l'ordre dans lequel les finaliseurs sont appelés est également non déterministe. Dans ce cas, un wrapper appelable d'exécution a également un finaliseur, qui appelle Marshal.FinalReleaseComObject sur lui-même, ce qui a pour résultat de décrémenter le nombre de références du côté COM de la clôture afin que cet objet COM puisse être libéré. Mais étant donné que l'ordre dans lequel les finaliseurs sont appelés est incertain, il est très possible que les finaliseurs des objets COM auxquels vos références d'objet se déclenchent avant le finaliseur de votre objet. Ainsi, le code dans votre finaliseur peut parfois fonctionner, mais, la plupart du temps, un ou plusieurs des wrappers d'appel exécutables que vos références d'objet auront déjà appelés leurs finaliseurs et l'objet COM sous-jacent aura été libéré avant que votre finaliseur arrive à exécuter son code.

33
Ran