Pierwsze pytanie:
powiedz, że tak
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string storedProc = "GetData";
SqlCommand command = new SqlCommand(storedProc, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID));
return (byte[])command.ExecuteScalar();
}
Czy połączenie zostaje zamknięte? Ponieważ technicznie nigdy nie dotarliśmy do końca, }
tak jak return
przedtem.
Drugie pytanie:
tym razem mam:
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
int employeeID = findEmployeeID();
connection.Open();
SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID));
command.CommandTimeout = 5;
command.ExecuteNonQuery();
}
}
catch (Exception) { /*Handle error*/ }
Teraz powiedzmy, że gdzieś w try
pliku pojawia się błąd i zostaje on przechwycony. Czy połączenie nadal jest zamykane? Ponownie, pomijamy resztę kodu w instrukcji try
i przechodzimy bezpośrednio do catch
instrukcji.
Czy myślę zbyt liniowo, jak to using
działa? ie Czy Dispose()
po prostu zostaje wywołany, gdy opuszczamy using
zakres?
źródło
try catch
wewnątrzusing
możesz jawnie.Commit
lub.Rollback
transakcje wcatch
. Jest to zarówno bardziej czytelne, jak i wyraźne, i pozwala na zatwierdzenie, jeśli ma to sens, biorąc pod uwagę typ wyjątku. (Transakcje niejawnie wycofują się,conn.Close
jeśli nie zostały zatwierdzone).Open
połączenie.using
gwarantuje tylko, żeDispose
zostanie wywołana metoda obiektu .Tak na oba pytania. Instrukcja using zostaje skompilowana do bloku try / final
jest taki sam jak
Edycja: Naprawianie rzutowania na jednorazowe http://msdn.microsoft.com/en-us/library/yh598w02.aspx
źródło
Oto mój szablon. Wszystko, czego potrzebujesz, aby wybrać dane z serwera SQL. Połączenie jest zamykane i usuwane, a błędy w połączeniu i wykonywaniu są wychwytywane.
* Poprawiono: 2015-11-09 *
Zgodnie z sugestią NickG; Jeśli denerwuje Cię zbyt wiele aparatów ortodontycznych, sformatuj w ten sposób ...
Z drugiej strony, jeśli pracujesz dla gier EA lub DayBreak, możesz po prostu zrezygnować z przerw między wierszami, ponieważ są one przeznaczone tylko dla osób, które muszą później wrócić i spojrzeć na Twój kod, a kogo to naprawdę obchodzi? Czy mam rację? To znaczy 1 linia zamiast 23 oznacza, że jestem lepszym programistą, prawda?
Uff ... OK. Wyciągnąłem to z mojego systemu i przez chwilę się bawię. Kontynuować.
źródło
conn.Close();
na końcu? Czyusing
oświadczenie nie robi tego za Ciebie poprzez utylizację?Dispose zostaje po prostu wywołane, gdy opuścisz zakres using. Celem „używania” jest zapewnienie programistom zagwarantowanego sposobu na pozbycie się zasobów.
Z MSDN :
źródło
Using
generuje próbę / w końcu wokół przydzielanego obiektu i wołaDispose()
do Ciebie.Oszczędza to kłopotów związanych z ręcznym tworzeniem bloku try / last i dzwonieniem
Dispose()
źródło
W pierwszym przykładzie kompilator C # faktycznie przetłumaczy instrukcję using na następującą:
Instrukcje Final zawsze będą wywoływane przed powrotem funkcji, więc połączenie będzie zawsze zamykane / usuwane.
Tak więc w drugim przykładzie kod zostanie skompilowany w następujący sposób:
Wyjątek zostanie przechwycony w instrukcji last i połączenie zostanie zamknięte. Wyjątek nie będzie widoczny w klauzuli zewnętrznej catch.
źródło
Napisałem dwie instrukcje using wewnątrz bloku try / catch i mogłem zobaczyć, że wyjątek jest przechwytywany w ten sam sposób, jeśli jest umieszczony w wewnętrznej instrukcji using , tak jak w przykładzie ShaneLS .
Bez względu na to, gdzie jest umieszczony tryb try / catch , wyjątek zostanie przechwycony bez problemów.
źródło