Durée de vie de l'objet lorsqu'il est créé et utilisé uniquement dans le cadre d'une instruction using

c# dapper

Question

Lorsqu'un objet est créé et utilisé uniquement dans le cadre d'une instruction using, est-il éliminé lors de la disposition de son instance IDisposable englobante? Si non, pourquoi ne serait-ce pas?

Par exemple, lors de l'utilisation de Dapper, j'ai souvent créé un objet anonyme dans la portée de SqlConnection avec l'impression qu'il sera éliminé plus tôt - cependant, j'ai lu récemment quelque chose de contraire.

using (var connection = new SqlConnection("Connection String"))
{
    var parameters = new
    { 
        Message = "Hello world!"
    };

    connection.Execute("INSERT INTO...", parameters);
}

Réponse acceptée

Votre instruction using est essentiellement équivalente à:

 var connection = new SqlConnection("Connection String");

 try
 {
     var parameters = new
     { 
         Message = "Hello world!"
     };
 }
 finally
 {
     if (connection != null)
     {
         ((IDisposable)connection).Dispose();
     }
 }

Comme vous pouvez le voir, il n'y a aucune raison pour que toute autre instance IDisposable créée dans le bloc try soit automatiquement éliminée pour vous. Si vous devez vous assurer que d'autres objets sont éliminés, imbriquer simplement en using instructions:

using (var connection = new SqlConnection("Connection String"))
{
     using (var otherDisposableObject = new ....)
     {
     } //otherDisposableObject disposed
} //connection disposed

Si une imbrication excessive entrave la lisibilité, vous pouvez simplement écrire les instructions comme suit:

using (var connection = new SqlConnection("Connection String"))
using (var otherDisposableObject = new ....)
using (var anotherDisposableObject = new ....)
using (var andAnotherDisposableObject = new ....)
{
} //andAnotherDisposableObject, anotherDisposableObject, otherDisposableObject and connection all disposed

Gardez à l'esprit que vous semblez mélanger la collecte des ordures avec la disposition d'un objet. Dans votre exemple, les parameters sont élégants pour la récupération de place une fois que l'exécution a quitté l'instruction d' using car il n'y a pas de référence en direct.

Lorsque la récupération de la mémoire est effectuée par le GC , cela peut très bien ne jamais se produire, en fonction de la pression de la mémoire de votre application. S'il est récupéré, il sera marqué comme valide pour la finalisation et le finaliseur de l'objet sera programmé pour s'exécuter. Encore une fois, si et quand cela se produit, c'est entièrement au GC .

Enfin, si le modèle IDisposable de l'objet est implémenté correctement et que le finaliseur est exécuté, Dispose() sera appelé (pour être précis, Dispose(false) sera appelé) et l'objet disposera des ressources non gérées qu'il pourrait contenir ( Les ressources gérées ne peuvent pas être éliminées en toute sécurité dans ce contexte, mais cela n'a pas vraiment d'importance, le GC finira par s'en occuper également.

Pour plus de détails sur la façon dont cela fonctionne ou même mieux, consultez le schéma IDisposable. Découvrez cette excellente réponse SO .




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi