2010-06-30 12 views
10

Zajmuję się rozwojem ASP.NET w VS i właśnie znalazłem interesującą sugestię małego kodu (myślę, że pochodzą one z coderush, ale mogę się mylić).Dlaczego muszę wywoływać dispose na formantach ASP.NET?

Ilekroć tworzę formanty, mówi mi, że powinienem używać dla nich instrukcji "using". Jestem trochę zdezorientowany co do tego, co tu się dzieje. z użyciem mój kod wygląda mniej więcej tak:

using (HtmlTableRow tableRow = new HtmlTableRow()) 
{ 
    tableRow.Attributes.Add("class", isOddRow ? "OddRow" : "EvenRow"); 
    listingTable.Rows.Add(tableRow); 
    addCell(tableRow, row, "issueId"); 
    addCell(tableRow, row, "Title"); 
    addCell(tableRow, row, "Type"); 
    addCell(tableRow, row, "Summary"); 
} 

Więc ja oczekuję, że w końcu z wykorzystaniem rachunku będzie zadzwonić wyrzucać na TableRow. Jednak dokumenty w bibliotece MSDN mówią:

Metoda usuwania pozostawia Kontrolę w stanie niezdatnym do użytku. Po wywołaniu tej metody, musisz zwolnić wszystkie odniesienia do kontrolki, aby pamięć , którą zajmował, mogła zostać odzyskana przez wyrzucanie elementów bezużytecznych.

Spodziewam się, że teraz mam obiekt, który nie może być użyty w mojej strukturze kontrolnej, aby mógł się zepsuć lub nie renderować. Jednak wszystko wydaje się działać dobrze.

Więc zastanawiam się, dlaczego wszystkie elementy sterujące są dostępne do użytku? Czy to dlatego, że niektóre z nich będą dostępne, i czynienie z nich wszystkich jednorazowymi środkami oznacza, że ​​jedno wezwanie do dysponowania na najwyższym poziomie może zostać przekazane rekursywnie do wszystkich kontrolek podrzędnych?

Myślę, że zrozumiałbym, gdyby nie fakt, że doktorzy wyraźnie mówią, że pozbycie się kontroli czyni ją niezdatną do użytku ... Czy doktorzy właśnie mylą się?

+0

W jaki sposób możemy obsłużyć osierocone obiekty (wspomniane przez @Toby), jeśli nie używamy bloku "używając"? – Lijo

Odpowiedz

14

Nie powinieneś tego robić. Trzeba tylko upewnić się, że listingTool znajduje się w kolekcji Controls, dzięki czemu zostanie usunięty po usunięciu strony. Obiekt listingTable jest odpowiedzialny za prawidłowe usunięcie wszystkich jego elementów podrzędnych.

Dlatego wszystkie obiekty Control implementują interfejs IDisposable. W ten sposób każda kontrola rodzicielska może wywołać Dispose na wszystkich swoich dzieciach bez wcześniejszego testowania/rzutowania każdego z nich. Każda kontrolka jest indywidualnie odpowiedzialna za określenie, czy rzeczywiście ma coś, co musi być oczyszczone, gdy wywołana zostanie jego metoda Dispose.

Dokumenty nie są błędne. Każdy poprawnie napisany obiekt, który implementuje IDisposable i ma dane stanu, które są rzeczywiście czyszczone podczas procesu utylizacji powinien rzucić wyjątek ObjectDisposedException, jeśli jakakolwiek z jego publicznych/chronionych/wewnętrznych właściwości lub metod jest dostępna po jej usunięciu. (Przyjmuje się nieprawidłowy stan po wywołaniu Dispose.) Niektóre typy zignorują tę regułę, jeśli w rzeczywistości nie mają niczego do wyczyszczenia i nie muszą martwić się o nieprawidłowy stan.

Powodem dostajesz propozycję zawinąć go w using bloku ponieważ analizator nie zdaje sobie sprawy, że listingTable będą wyrzucać jej Rows kolekcję, która będzie dysponować każdy z obiektów wierszy, które zostały dodane do niego. Ponadto, jeśli zostanie zgłoszony wyjątek między HtmlTableRow tableRow = new HtmlTableRow() i listingTable.Rows.Add(tableRow), obiekt HtmlTableRow zostanie "osierocony" i nie będzie w hierarchii żadnego innego obiektu w hierarchii IDisposable. Analiza kodu chce, abyś użył bloku try/finally, aby natychmiast pozbyć się HtmlTableRow, jeśli tak się stanie.

+1

Dzięki. Miałem podejrzenia co do tego, ale dobrze jest uzyskać trochę więcej szczegółów na temat tego, co się tutaj dzieje. Nie brałem nawet pod uwagę "osierocenia" kontroli. – Chris

+0

Jak możemy obsłużyć obiekty "osierocone", jeśli nie używamy bloku "używając"? – Lijo

+0

@Lijo: Użyj bloku try/finally – Toby