-
Singleton et Dispose
Bonjour, j'ai une question conceptuelle concernant la libération des ressource (via Dispose ou Finalizer) lorsqu'on utilise un Singleton.
En effet j'ai une classe A implémenté sous forme de singleton qui utilise des références à Excel.
J'ai n instance d'une classe B, qui utilise l'unique instance de la classe A.
(Et probablement m instance d'une classe C qui utilise aussi A)
J'aimerais que la classe A ferme le fichier excel lorsque plus aucune classe B (ou C) ne l'utilise.
J'ai initialement pensé a utiliser le destructeur mais l'objet est maintenu en vie a cause de la référence statique présente dans le singleton.
Je ne peux pas appeler la méthode Dispose de A depuis le Dispose de B étant donné qu'il y a peut être d'autre instance de B qui peuvent encore être en vie.
Bref le problème me parait simpliste mais je n'ai aucune solution qui semble marcher ce qui me désespère un peux
-
Une solution simple à implémenter :
Depuis ton singleton tu incrémentes un compteur à chaque fois que l'instance est récupérée par B (ou C)
Tu crées une méthode ReleaseToken() dans A qui décrémente le compteur, et ferme le fichier Excel quand le compteur atteind 0.
Attention toute fois, si tu oscilles souvent entre 1 et 0 c'est peut-être mauvais pour les perfs.
Depuis ton instance de B, tu fais appelles la méthode ReleaseToken() quand tu n'en a plus besoin.
Est-ce que ça répondrait à ton besoin ?
-
A la solution proposé par Er3van, j'an ajourterai une autre, à coupler avec la sienne. Quant ton compteur de "token" arrive à 0, tu déclenche un timer, dont le temps est à fixer pragmatiquement, et tu libères la resource quand le timer est échu. Ainsi,sous réserve d'un choix judicieux de l'interval, tu évites les oscillations trop nombreuses entre 0 et 1.
-
En fait j'ai déjà testé un système de comptage de référence assez similaire à la solution d'Er3van a la différence près que la fermeture d'Excel était dans le dispose, et que la méthode ReleaseToken appelait le dispose lorsque le compteur arrivait a 0 (méthode inspiré du comptage de référence COM).
Mais pour une raison que je n'ai pas trop compris, le code semblait passer plusieurs fois d'affilé dans le code du Dispose.Je m’étais dit que du coup le problème provenait peut être du fait que ma méthode ReleaseToken n'était pas threadsafe et que du coup ce n’était pas une bonne solution.
Ceci dit avec du recul, il n'y a aucune raison que mes instances de B soient disposées "au même moment", vu que je n'utilise pas de thread dans ma dll.
-
Pour répondre à ta question sur de threads, le garbage collector tourne dans un autre thread et c'est dans celui-ci que dispose est appelé.
Une méthode pour être plus précis qu'un simple compteur c'est d'utiliser System.WeakReference et de répertorier tes objets dans une list de l'instance du singleton. Tu n'aurais pas besoin de faire de compteur et tout, et tu n'irais pas plus vite que la garbage collector, tu pourrais fermer excel quand le garbage collector à bien ramasser tous les objets référencés dans ton singleton. Il faudra quand même un petit timer pour parcourir la liste.
-
Ca me parait une très très bonne idée, je vais tacher d'essayer ça !