Y a-t-il des cas particuliers où je devrais (ou ne devrait pas) utiliser des blocs “using”:
using(SomeType t = new SomeType()){ ... }
Lorsque la classe SomeType
implémente IDisposable
.
Certains objects nécessitent des actions à entreprendre lorsque vous en avez fini avec eux. Cela est généralement dû au fait que l’object utilise une sorte de ressource à supprimer. Par exemple, si vous avez un object fichier de classe File et que cet object ouvre un fichier du système de fichiers, le fichier du système de fichiers devra être fermé à nouveau.
Si vous venez de quitter l’object fichier et que vous avez oublié d’appeler file.Close (), il ne serait pas nettoyé tant que le récupérateur de place (GC) ne s’exécuterait pas et que rien n’utilisait encore l’object fichier. Lorsque le ramasse-miettes s’exécute, il faut laisser le CLR (Common Language Runtime) décider. Si le CPG ne s’exécute pas pendant un certain temps après que vous ayez fini avec le fichier, le fichier pourrait restr ouvert pendant longtemps. Cela peut poser un gros problème s’il y a beaucoup d’objects de fichiers, ou si quelque chose veut ouvrir un fichier, mais que ce n’est pas possible car l’object de fichier que vous avez laissé est toujours en attente.
Pour résoudre ce problème, C # a l’interface IDisposable. Cela a une méthode appelée Dispose. Les classes nécessitant un nettoyage implémentent cette méthode Dispose. Cela vous donne un moyen standard de nettoyer tous les objects qui utilisent des ressources. Il y a beaucoup de classes qui ont besoin d’appeler Dispose. Le problème est que le code est recouvert d’appels à Dispose, et qu’ils sont difficiles à suivre car l’endroit où vous avez créé l’object et que vous appelez Dispose pour le nettoyer sont différents. Donc, il fallait beaucoup regarder autour du code et faire très attention à vérifier qu’il y avait des appels à Dispose au bon endroit.
Pour résoudre ce problème, C # a introduit le mot-clé “using”. Vous pouvez placer un mot-clé «using» à l’endroit où vous créez un object, ce qui garantit que Dispose sera appelé pour vous. Cela garantit que Dispose sera appelé quoi qu’il arrive … même s’il existe une exception dans le corps de l’instruction using.
Donc, vous devriez utiliser ‘using’ quand vous voulez être sûr qu’un object qui alloue des ressources sera nettoyé.
using ne peut être utilisé que pour les objects déclarés sur la stack, c’est-à-dire dans une fonction. Cela ne fonctionne pas pour les objects déclarés en tant que membres d’une classe. Pour eux, vous devez appeler Dispose vous-même. Vous devrez peut-être implémenter Dispose dans votre classe pour qu’app puisse appeler Dispose sur tous les objects membres qui en ont besoin.
Les objects courants nécessitant l’utilisation d’appels sont les suivants: fichiers, connexions à la firebase database, objects graphiques tels que Pen et Brush.
Parfois, il est également utilisé lorsque vous voulez que deux opérations se produisent ensemble. Par exemple, si vous voulez écrire une instruction de journal lorsqu’un bloc de code est entré et à la fermeture, vous pouvez écrire une classe de journal que vous pouvez utiliser comme ceci:
using( Log log = new Log("Doing stuff") ) { // Stuff }
Le constructeur de la classe de journalisation peut être amené à écrire le message, et la méthode Dispose peut également l’écrire. Implémentez le finaliseur (~ Log) à affirmer si la méthode Dispose n’est pas appelée pour s’assurer que l’utilisation de ‘est mémorisée autour du’ nouveau journal ‘.
Utilisez using
chaque fois que le type implémente IDisposable
, à moins que vous ne l’encadriez dans un bloc try
/ catch
, vous pourriez aussi bien (selon ce que vous préférez) utiliser un bloc finally
.
Je vois beaucoup d’autres réponses lorsque vous devriez avoir une déclaration d’ using
. Je veux aborder quand spécifiquement ne devrait pas avoir une déclaration d’ using
:
Si vous devez utiliser votre object en dehors de la scope de la fonction en cours, ne pas using
bloc. Un bon exemple est une méthode de fabrique qui renvoie une connexion à une firebase database ou une méthode devant renvoyer un lecteur de données. Dans l’un ou l’autre de ces cas, si vous créez votre object avec une instruction using
, il sera éliminé avant que la méthode ne soit renvoyée, et donc non utilisable en dehors de la méthode.
Maintenant, vous voulez toujours être sûr que ces objects sont disposés, donc vous pouvez toujours vouloir une instruction quelque part. Ne l’incluez simplement pas dans la méthode où l’object est réellement créé. Au lieu de cela, vous pouvez envelopper l’appel de fonction lui-même dans une instruction using
.
Lorsque SomeType implémente IDisposable.
Cela indique à votre développeur que SomeType utilise des ressources non gérées qui doivent être nettoyées.
Exemple:
using(SqlConnection MyConnection = new SqlConnection("Connection ssortingng")) { MyConnection.Open(); //... // 1. SQLConnection is a type that implements IDisposable // 2. So you can use MyConnection in a using statement // 3. When using block finishes, it calls Dispose method of // SqlConnection class // 4. In this case, it will probably close the connection to // the database and dispose MyConnection object }
Vous pouvez créer vos propres objects qui implémentent IDisposable:
public class MyOwnObjectThatImplementsIDisposable : IDisposable { //... some code public void Dispose() { // Put here the code you want to be executed when the // using statement finish. } }
Vous pouvez donc utiliser un object de type MyOwnObjectThanImplementsIDisposable dans une instruction using:
using(MyOwnObjectThatImplementsIDisposable MyObject = new MyOwnObjectThatImplementsIDisposable) { // When the statement finishes, it calls the // code you´ve writed in Dispose method // of MyOwnObjectThatImplementsIDisposable class }
J’espère que cela t’aides
Dans ce contexte, l’instruction using
est pratique pour les types qui implémentent IDisposable. Lorsque le bloc de code quitte la scope de l’instruction using
, Dispose()
est appelé implicitement. C’est une bonne habitude lorsque vous travaillez avec des objects que vous souhaitez éliminer immédiatement après utilisation.
Une instance spécifique dans laquelle vous devez faire attention en utilisant un bloc using
est avec un client de service WCF .
Comme indiqué dans cet article MSDN , encapsuler un client WCF (qui implémente IDisposable
) dans un bloc using
pourrait masquer les erreurs entraînant le départ du client dans un état défaillant (comme un problème de délai d’attente ou de communication). En bref, lorsque Dispose()
est appelée, la méthode Close()
du client se déclenche, mais lance et génère une erreur car son état est défaillant. L’exception d’origine est ensuite masquée par la deuxième exception. Pas bon.
Il existe différentes solutions de contournement, y compris une dans l’article MSDN lui-même. D’autres peuvent être trouvés chez IServiceOriented et blog.davidbarret.net .
Je préfère la dernière méthode, moi-même.
Si vous souhaitez une règle récapitulative. A chaque fois qu’un object utilisant IDisposable où vous n’auriez pas de prise, utilisez using. En utilisant essentiellement ce motif:
try { //instantiate and use object } finally { //dispose object }
Si vous n’avez pas besoin de prise, l’utilisation peut vous sauver, ce qui est une bonne chose.
La règle principale est la suivante: * Utilisez l’instruction USING lorsque des objects implémentent une interface IDisposable.
Cette interface fournit la méthode Dispose, qui doit libérer les ressources de l’object. Si cette méthode n’est pas appelée, l’object rest en mémoire aussi longtemps que CLR veut effectuer la récupération de place. Si le programmeur utilise l’instruction USING, l’object sera supprimé à la fin et toutes les ressources seront libres.
Il est très important que toutes les ressources qui ne sont plus utilisées soient gratuites dès que possible.
Pour plus d’informations à ce sujet, visitez ce lien: microsoft
Peut-être convient-il de mentionner que la raison sous-jacente à l’ajout de «using» à lo C # languge est la suivante: certaines ressources peuvent être assez rares pour qu’il ne soit pas logique d’attendre que le GC appelle IDisposable. Par exemple, les connexions à la firebase database. Si vous utilisez try / catch / finally, vous ne vous retrouverez pas avec une connexion en suspens, mais la connexion sera suspendue jusqu’à ce que GC ne démarre pas et cela peut prendre un certain temps (si vous ne le fermez pas explicitement). Si vous utilisez “using” (excusez le jeu de mots), vous libérerez la connexion immédiatement même si vous avez oublié de la fermer et même si certaines exceptions se sont produites dans le bloc using.
Une autre raison, mentionnée dans le post précédent, est que les programmeurs n’utilisent pas toujours le nettoyage final. Si vous n’utilisez pas enfin en cas d’exception, vous vous retrouvez avec des ressources qui fuient…
Une situation est lorsque vous voulez faire quelque chose au début d’un bloc de code, puis le défaire à la fin du bloc, sans condition (même s’il y a un lancer).
Le ctor de la classe disponible que vous construisez (et appelez avec using) exécutera l’action, puis la méthode Dispose annulera cette action. C’est généralement comme ça que je l’utilise.
D’autres personnes ont déjà mentionné “IDisposable”.
Mais l’une des mises en garde lors de l’utilisation de l’instruction “using” est que, toutes les exceptions lancées dans “using” ne seront pas interceptées, même si “SomeType” sera supprimé indépendamment du fait.
Donc, dans l’extrait suivant,
using (SomeType t = new SomeType()){ throw new Exception("thrown within using"); }
throw new Exception("thrown within using");
ne doit pas être ignoré.
J’appendais aussi que vous utilisez une instruction using()
si quelque chose implémente IDispose
et également si quelque chose que vous voulez éliminer retient les ressources NON-MANAGED telles que les connexions aux bases de données et les descripteurs de fichiers.
Si c’est un object normal avec une List
, où T est comme un object Customer
qui contient des noms et une adresse, vous n’avez pas besoin de le faire. Le ramasse-miettes est assez intelligent pour gérer cela pour vous. Mais le ramasse-miettes NE renverra PAS les connexions au pool de connexions ni ne fermera les descripteurs de fichiers.