Comment savoir si un IDisposable référence d'objet est disposé?
Est-il une méthode, ou d'une autre lumière-poids moyen, pour vérifier si une référence à un objet supprimé?
P. S. - C'est juste une curiosité (bien dormir, pas dans le code de production). Oui, je sais que je peux attraper le ObjectDisposedException
lors de la tentative d'accès à un membre de l'objet.
- Je ne sais pas. Il semble curieux qu'il n'y a pas un
bool IsDisposed { get; }
déclaration surSystem.IDisposable
. - Le
Dispose
méthode dirige un objet à la libération de tout et de toutes les ressources qu'il a acquis mais non encore publié. Si un objet ne tient jamais ses ressources, sesDispose
méthode en général n'a rien à faire; si le type déclarevoid IDisposable.Dispose() {};
il peut ignorerIDisposable
avec pas par exemple les frais généraux. UnIsDisposed
propriété qui devrait être vrai à la suite de touteDispose
appel nécessiterait l'ajout d'une inutile indicateur Booléen à chaque instance de beaucoup de types qui, autrement, pourraient ignorerDispose
. - Mais, où que vous appeler une méthode sur un objet qui implémente
IDisposable
, comment pouvez-vous vérifier s'il a été éliminé en premier? Plutôt que de supposer qu'il n'est pas le cas et que l'interception d'une exception? Ou d'une certaine manière vous êtes censé gérer la durée de vie de sorte que vous devriez toujours savoir si il est éliminé ou pas? - Vous ne devez pas utiliser un objet sans savoir qu'il n'a pas été et ne seront pas éliminés, sauf dans les cas où l'on est préparé à l'égard de l'élimination de l'objet par le code extérieur comme un signal pour annuler des actions en cours avec elle. Un
IsDisposed
drapeau peut aider à prévenir le code de perdre du temps sur des opérations qui ne peut pas réussir, mais on aurait encore besoin de gérer des exceptions dans le cas d'un objet devient disposé entre laIsDisposed
contrôle et la tentative de l'utiliser. WeakReference
semble pertinent ici. Ce n'est pas exactement un IDipose avais détecteur, mais il ne vous dire si c'est de la GC avait- Tout cela n'aide pas tous les
IDisposable
s, et il nécessite l'avance de temps pour la planification, si vous avez unSystem.ComponentModel.IComponent
, il y a unDisposed
cas, vous pouvez joindre à, comme indiqué dans le Moïse réponse
Vous devez vous connecter pour publier un commentaire.
Ça dépend, il y a
IDisposable
objets qui permettent d'appeler leDispose
méthode autant que vous voulez, et il y aIDisposable
objets jeterObjectDisposedException
. Dans un tel cas, ces objets doivent suivre l'état (généralement mis en œuvre avec un champ booléenisDisposed
).ObjectDisposedException
selon la façon dont le modèle a été mis en œuvre).IDisposable
correctement. La question est de savoir comment traiter avec déjà mis en place classes.System.Threading.Tasks.Task.WaitAll(Task[])
sera levée d'une exception si aucun des tâches ont été éliminés. Ce comportement n'est pas souhaitable, parce que je veux attendre jusqu'à ce que tous les autres threads, et ignorez-le. Le seul moyen que j'ai pour gérer cela est de vérifier si l'objet a été éliminé avant de l'ajouter à l'attente de tableau. MALHEUREUSEMENT, je ne peux pas ajouter un champ booléen sans la création d'une classe dérivée et de l'aide que partout dans mon code.Pas - défaut de mise en œuvre de IDisposable modèle ne prend pas en charge
System.Windows.Forms.Control
a unIsDisposed
propriété qui est la valeur true aprèsDispose()
est appelé. Dans votre propre IDisposable objets, vous pouvez facilement créer un bien similaire.Il n'y a rien de construit en que le permettent. Vous auriez besoin d'exposer une IsDisposed propriété booléenne qui reflète interne disposé drapeau.
IDisposablePlus
ou quoi que ce soit) qui hérite deIDisposable
et comprendbool IsDisposed { get; }
. Cela rend plus facile pour savoir qui de vosIDisposable
support des objetsIsDisposed
.Si ce n'est pas votre classe et il ne fournit pas un IsDisposed propriété (ou quelque chose de similaire - le nom n'est qu'une convention), alors vous n'avez aucun moyen de le savoir.
Mais si c'est votre classe et vous êtes à la suite de la canonique IDisposable mise en œuvre, alors il suffit d'exposer la _disposed ou _isDisposed domaine de la propriété et de vérifier.
La
Dispose
méthode est nécessaire pour effectuer le nettoyage sera nécessaire avant qu'un objet est abandonné; si aucun nettoyage n'est nécessaire, il n'est pas nécessaire de faire quoi que ce soit. Nécessitant un objet à garder une trace de savoir s'il a été disposé, même lorsque leDispose
méthode de rien sinon, exigerait beaucoup deIDisposable
des objets pour ajouter un drapeau pour très peu de bénéfices.Il aurait pu être utile si
IDisposable
inclus deux propriétés--qui indique si un objet nécessaire de disposer, et l'un des qui a indiqué que l'objet n'avait pas été rendu inutile par l'élimination. Pour les objets où l'immersion en fait quelque chose, les deux valeurs doit d'abord être vrai, et il est devenu faux aprèsDispose
. Pour les objets où l'immersion n'a pas besoin de faire tout le nettoyage, la première méthode pourrait toujours retourner false et la seconde un vrai, sans avoir à stocker un drapeau n'importe où. Je ne pense pas qu'il y a moyen de ceux-ci peuvent être ajoutés .NET maintenant, si.IDisposable
n'ont pas deDisposed
propriété est qu'elle aurait été perçu comme étrange d'avoir des objets où l'appelantDispose
ne serait pas définir cette propriété pourtrue
, mais en exigeant que les objets de savoir siDispose
a été appelé dans les cas où ils ne l'auraient pas de raison de soins permettrait d'ajouter un coût important et peu d'avantages.Je vois c'est vieux, mais je n'ai pas de réponse.
Certains pas tous les objets jetables comme un ensemble de données ont disposé de l'événement que vous pouvez joindre.
Disposed
événement est un membre deSystem.ComponentModel.IComponent
interface.Ce que j'aime à faire est de déclarer les objets sans l'initialiser, mais de définir leurs valeurs par défaut à
Nothing
. Puis, à la fin de la boucle j'écris:Voici un exemple complet:
Cela fonctionne également idéal pour mettre vos objets principaux dans le haut de la routine, de les utiliser à l'intérieur d'un
Try
routine, puis de les jeter dans uneFinally
bloc:Using
déclaration? Que certainement existé de retour en 2013, lorsque cette réponse a été écrit.inputPdf
a été définie à une valeur (autres que de ne Rien faire), votre réponse ne montre aucun moyen de savoir siinputPdf
a été disposé. Vous pourriez partie adresse de ce par la mise eninputPdf = Nothing
après l'élimination. Toutefois, cela n'aide pas du tout autres variables qui ont été pointées vers le même objet queinputPdf
. C'est si vous n':inputPdf = New PdfReader
,Dim pdf2 As PdfReader = inputPdf
,inputPdf.Dispose
,inputPdf = Nothing
, il n'y aurait toujours pas de moyen de savoir quepdf2
est éliminé (c'est le même objet queinputPdf
).