Appelant Dispose() vs lorsqu'un objet est mis hors de portée/méthode de finitions
J'ai une méthode, qui a un try/catch/finaly
bloc à l'intérieur. Dans le bloc try, je déclare SqlDataReader
comme suit:
SqlDataReader aReader = null;
aReader = aCommand.ExecuteReader();
Dans le finally
bloc, les objets qui sont manuellement cédés sont ceux qui sont définis au niveau de la classe. Afin de voir les objets dans la méthode à mettre en œuvre IDisposable
, comme SqlDataReader
ci-dessus, sont-ils automatiquement éliminés? Close()
est appelée sur aReader
après une boucle while s'exécute pour obtenir le contenu du lecteur (qui devrait être Dispose()
que les appels Close()
). Si il n'y a pas d'appel à la Close()
, serait-ce l'objet sera fermé/éliminés automatiquement lorsque la méthode de finitions ou de l'objet est hors de portée?
EDIT: je suis conscient de la using
déclaration, mais il y a des scénarios qui sont source de confusion pour moi.
Vous devez vous connecter pour publier un commentaire.
Non, les objets ne sont pas automatiquement éliminés lorsqu'ils passent hors de portée.
Ils ne sont même pas garanti d'être éliminés si/quand ils sont récupérées, bien que de nombreux
IDisposable
objets de mettre en œuvre un "repli" finaliser pour aider à s'assurer qu'ils sont finalement éliminés.Vous resposible pour s'assurer que tout
IDisposable
objets sont disposés, de préférence en les enveloppant dans unà l'aide de
bloc.Vous devez utiliser un
using {...}
bloc pour envelopper votre IDisposable objets dans leDispose()
méthode (qui pour SqlDataReader passe à laClose()
méthode sera appelée lors de l'utilisation de bloc se termine. Si vous n'utilisez pasusing
, l'objet sera pas être automatiquement éliminés lorsqu'elle est hors de portée, il sera à l'objet finaliseur, si elle en a un, pour se débarrasser de ressources lorsqu'il est des ordures collectéesLe modèle dispose ne fait aucune garantie concernant les objets qui feront appel Disposer sur laquelle d'autres objets; il peut arriver parfois, mais vous ne devriez pas de soins. Au lieu de cela, il est de votre responsabilité de vous assurer que dispose() est appelée pour toutes les IDisposable objets. La meilleure façon de le faire est avec la
using
déclaration. Par exemple:Je suis d'accord avec tout ce qui précède. Assurez-vous que vous appelez
Dispose()
vous-même, et de la manière la plus simple pour cela est avec leusing
déclaration (vous pouvez aussi le faire vous-même dans lefinally
bloc, ce qui est plus détaillé, mais il est parfois nécessaire). Si vous ne le faites pas, vous pouvez trouver votre application fuite de ressources non managées, tels que les poignées, ou même une mémoire non managée, surtout si quelque part en dessous de tout cela certains composants COM sont utilisées, la ou les appels sont en cours dans l'API Win32. Cela peut évidemment conduire à des performances et des problèmes de stabilité, ainsi que excessive de l'utilisation des ressources.Tout simplement parce que les objets qui implémentent
IDisposable
"devrait" mettre en œuvre un finaliser qui appelle leurDispose(bool disposing)
méthode pour libérer des ressources non managées, n'est pas une garantie que ce sera le cas, alors vous avez certainement ne devriez pas compter sur elle. Voir, par exemple, http://msdn.microsoft.com/en-us/library/b1yfkh5e%28VS.71%29.aspx pour plus d'informations sur ce point.Aussi, autre chose à garder à l'esprit, c'est que si votre type a des membres qui sont jetables, votre type devrait mettre en place
IDisposable
(à moins que le cycle de vie de ces membres est géré par un autre type, qui, évidemment, peut être très salissant), ou, si vous utilisez uniquement les membres dans une méthode, ou de mettre en œuvre l'un morceau particulier de la fonctionnalité, vous devez envisager de faire d'eux des variables locales et des paramètres dans les méthodes qui les utilisent.Je suis intrigué par la mention "Dans le bloc finally, les objets qui sont manuellement cédés sont ceux qui sont définis au niveau de la classe." Par les objets mis au niveau de la classe, entendez-vous les champs? Vous ne devriez probablement pas de l'élimination de ces à l'intérieur d'une méthode ordinaire, parce que la durée de vie des champs est imprévisible et dépend des méthodes qui vous est arrivé d'avoir appelé. Il serait préférable de mettre en œuvre IDisposable et de disposer de champs dans votre méthode dispose.
La À l'aide de déclaration aider?