Czy Dispose nadal jest wywoływany, gdy wyjątek jest wrzucany do instrukcji using?

W poniższym przykładzie, czy połączenie zostanie zamknięte i usunięte, gdy zostanie wyrzucony wyjątek, jeśli znajduje się w instrukcji using?

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

Wiem, że poniższy kod upewni się, że tak jest, ale jestem ciekaw, jak robi to using statement.

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();
}

Powiązane:

jaki jest właściwy sposób zapewnienia zamknięcia połączenia SQL po wyrzuceniu wyjątku?
Author: Community, 2009-02-06

2 answers

TAK, using zawija Twój kod w blok try / finally, gdzie finally część wywoła Dispose(), jeśli istnieje. Nie będzie jednak wywoływać Close() bezpośrednio, ponieważ sprawdza tylko, czy zaimplementowany jest interfejs IDisposable, a tym samym metoda Dispose().

Zobacz też:

 90
Author: Jeff Yates,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:32:17

Oto jak reflector dekoduje IL wygenerowany przez Twój kod:

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

Więc odpowiedź brzmi tak, zamknie połączenie, jeśli

DoStuff()
rzuca wyjątek.
 17
Author: Florin Sabau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 22:58:23