120 votes

Dispose est-il toujours appelé lorsqu'une exception est levée à l'intérieur d'une instruction using ?

Dans l'exemple ci-dessous, la connexion va-t-elle se fermer et être éliminée lorsqu'une exception est levée si elle se trouve à l'intérieur d'une zone de using déclaration ?

using (var conn = new SqlConnection("..."))
{
    conn.Open();
    // stuff happens here and exception is thrown...
}

Je sais que le code ci-dessous s'en assurera, mais je suis curieux de savoir comment l'utilisation de l'instruction le fait.

var conn;
try
{
    conn = new SqlConnection("...");
    conn.Open();
    // stuff happens here and exception is thrown...
}
// catch it or let it bubble up
finally
{
    conn.Dispose();
}

En rapport :

Quelle est la bonne façon de s'assurer qu'une connexion SQL est fermée lorsqu'une exception est levée ?

129voto

Jeff Yates Points 36725

Oui, using enveloppe votre code dans un bloc try/finally où l'élément finally la partie appellera Dispose() s'il existe. Cependant, il n'appellera pas Close() directement, car il ne vérifie que l'existence de l'élément IDisposable qui est mise en œuvre et, par conséquent, l'interface Dispose() méthode.

Voir aussi

21voto

AJFaraday Points 101

C'est ainsi que reflector décode l'IL généré par votre code :

private static void Main(string\[\] args)
{
    SqlConnection conn = new SqlConnection("...");
    try
    {
        conn.Open();
        DoStuff();
    }
    finally
    {
        if (conn != null)
        {
            conn.Dispose();
        }
    }
}

La réponse est donc oui, il fermera la connexion si

DoStuff()lance une exception.

-2voto

Chad Points 9

Dispose() n'est pas appelé dans ce code.

class Program {
    static void Main(string[] args) {
        using (SomeClass sc = new SomeClass())
        {
            string str = sc.DoSomething();
            sc.BlowUp();
        }
    }
}

public class SomeClass : IDisposable {
    private System.IO.StreamWriter wtr = null;

    public SomeClass() {
        string path = System.IO.Path.GetTempFileName();
        this.wtr = new System.IO.StreamWriter(path);
        this.wtr.WriteLine("SomeClass()");
    }

    public void BlowUp() {
        this.wtr.WriteLine("BlowUp()");
        throw new Exception("An exception was thrown.");
    }

    public string DoSomething() {
        this.wtr.WriteLine("DoSomething()");
        return "Did something.";
    }

    public void Dispose() {
        this.wtr.WriteLine("Dispose()");
        this.wtr.Dispose();
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X