2013-08-13 16 views
8

W this thread pojawia się sugestia, że ​​po operacji wystąpienie obiektu SqlDataAdapter jest usuwane jawnie, podobnie jak w przypadku.Czy muszę jawnie dysponować SqlDataAdapter?

String connString = @"your connection string here"; 
String query = "select * from table"; 

SqlConnection conn = new SqlConnection(connString);   
SqlCommand cmd = new SqlCommand(query, conn); 
conn.Open(); 
SqlDataAdapter da = new SqlDataAdapter(cmd); 
da.Fill(dataTable); 
conn.Close(); 
da.Dispose(); 

Czy to naprawdę konieczne? A co z GC?

Odpowiedz

6

Zaleca się ręczne usuwanie obiektów IDispozycyjnych. Jest miły składnia skrót do tego:

using (SqlConnection con = new SqlConnection(connstring)) 
using (SqlCommand com = new SqlCommand()) 
using (SqlDataAdapter da = new SqlDataAdapter()) 
{ 
    com.Connection = con; 
    //etc.. 
} 

ten sposób kompilator zadba Dispose jest wywoływana na wszystkich obiektów utworzonych w „użyciu” po kodzie w nawiasach klamrowych zakończeniu wykonywania (używa try..finally zrobić to).

GC nie ponosi odpowiedzialności za wywoływanie Unieszkodliwianie obiektów, głównym zadaniem jest zbieranie obiektów z sterty, które nie są już przywoływane.Jedynym wyjątkiem od tego jest to, czy twoja klasa jest możliwa do sfinalizowania. W takim przypadku GC upewni się, że finalizator twojego obiektu zostanie wywołany jako pierwszy, a następnie zostanie zebrany. Możesz wywołać Dispose w Finalizerze i istnieje dobry wzór dla tego, zwany "Dispose Method": http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

Ale ogólną zasadą jest (z kilkoma wyjątkami): Jeśli tworzysz obiekt implementujący IDisposable, Twoim obowiązkiem jest wywołać utylizację.

5

Od przykładzie kodu obejmują w acrticle MSDN dla SqlDataAdapter Class

private static DataSet SelectRows(DataSet dataset, string connectionString,string queryString) 
{ 
    using (SqlConnection connection = 
     new SqlConnection(connectionString)) 
    { 
     SqlDataAdapter adapter = new SqlDataAdapter(); 
     adapter.SelectCommand = new SqlCommand(
      queryString, connection); 
     adapter.Fill(dataset); 
     return dataset; 
    } 
} 

SqlConnection jest zamknięty w wykorzystaniem klauzuli, ale nie SqlDataAdapter.

Więc tak, nie jest to wymagane.

To powiedziawszy, niektórzy przechodzą w kierunku Jeśli implementuje IDisposable, wyrzuć go.

W takim przypadku można również zawinąć SqlDataAdapter w postaci using statement. Od tej połączonej artykuł:

co do zasady, w przypadku korzystania z IDisposable obiektu, należy zadeklarować i instancję w użyciu instrukcji.

1
String connString = @"your connection string here"; 
String query = "select * from table"; 

SqlConnection conn = new SqlConnection(connString);   
SqlCommand cmd = new SqlCommand(query, conn); 
conn.Open(); 
**Using(SqlDataAdapter da = new SqlDataAdapter(cmd)) 
{ 
    da.Fill(dataTable); 
    conn.Close(); 
}** 

Korzystanie będzie pozbyć się go dla Ciebie po zabawie osiągnęły koniec bloku.

+5

Dodaj również 'using' dla połączenia .... To jest najważniejszy zasób tutaj. –

2

Z reguły ... tak, robisz.
W niektórych przypadkach połączenie z Dispose nie jest wymagane, ale te przypadki są oparte na szczegółach implementacji i nie powinny być traktowane jako podejście ogólne.

Jednorazowe nie dotyczy zbierania śmieci. Chodzi o deterministyczne oczyszczanie zasobów. Te rzeczy to wszechświaty równoległe.

GC może odebrać obiekt, który implementuje IDisposable bez połączenia z Dispose. Ale jeśli ten obiekt trzyma uchwyt systemu operacyjnego, na przykład masz dwa sposoby: albo zwolnij uchwyt natychmiast (zadzwoń Dispose), albo czekaj na finalizator (ale gdy finalizator będzie działał, zna tylko GC).

Gdy zasoby są zarządzane, sytuacja jest jeszcze gorsza.
Zarządzane zasoby nie powinny być wydawane w finalizatorach. W związku z tym za każde oczyszczanie zasobów odpowiada metoda Dispose. Jeśli nie zadzwonisz pod numer Dispose, zarządzane zasoby nigdy nie zostaną oczyszczone (najpopularniejszym przykładem jest anulowanie subskrypcji), które przenosi Cię do wycieków pamięci.

Powiązane problemy