Co wlasciwie robi metoda dispose()

0

Witam,
mam takie pytanie a w zasadzie dwa pytania

  1. co wlasciwie robi funkcja dispose(). Bo wszedzie gdzie czytam napisane jest ze sluzy ona do usuwania obiektow. Ale kiedy ja sobie zobie na przyklad tak

jakisTamObiekt.Dispose() //oczywiscie klasa korzysta z interfejsu IDisposable

to pozniej dalej moge sie do niego odwolywac. Czy w metodzie Dispose musze umiescic jakis kod kotry powoduje ze obiekt zostanie faktycznie usuniety? Bo przeciez do destruktora sie nie moge odwolac?

  1. Drugie pytanie to w zasadzei przyklad

Otoz mam 2 klasy z ktorych tworze po jednym obiekcie - niech to beda obiekty
a) Obserwator
b) Obserwowany

Obiekt Obserwowany ma zdefiniowane zdarzenie np OnZdarzenie, a obiekt Obserwator dodaje do tego zdarzenia jakas swoja funkcje np. Modyfikuj. Czyli calosc dziala tak ze Gdy w obiekcie Obserwowany wystapi zdarzenia OnZdarzenie to w obiekcie Obserwator zostanie wywolana metoda Modyfikuj.

Teraz pytanie - czy GarbageCollector moze usunac "samowolnie" obiekt Obserwator jesli jedynym jego przejawem istnienia bedzie tylko to, ze jest powiazany z zdarzeniem OnZdarzenie - pewnie nie moze - czy mam racje?
A jesli tak, to jak nalezy usunac taki obiekt (zalozmy ze chce go usunac). Tak jak pisze w pytaniu 1 - metoda dispose() z moich obserwacji nie usuwa obiektu i nadal moge sie do niego odwolywac - ale moze sie myle:-) (pewnie tak)

Pewnie te pytania sa banalne, za co z gory przepraszam, ale ucze sie C# od 1,5 miesiaca i jest to w zasadzie moj 1 jezyk, wiec nie wszystko jeszcze jest dla mnie jasne.
Z gory dzieki za odpowiedz

0

C# to twój pierwszy język? A skąd się uczysz tego języka jeśli można spytać, z jakiejś książki, strony internetowej?

Odnośnie funkcji Dispose() to jej wywołanie faktycznie niszczy wszystkie zasoby obiektu. A dlaczego można się dalej odwoływać do tego obiektu? Ja to widze tak(jak mówie źle to sprostujcie):

Proces niszczenia objektu nie polega na wyzerowaniu pamięci, której ten obiekt zajmował. Program dostaje tylko informacje, że ta pamięć jest już wolna i gotowa do wykorzystania przez inne obiekty. Po wywołaniu Dispose() pozostaje referencja do miejsca w pamięci, w której istniał obiekt. A zatem dalej można się do niego odnosić, choć będzie to niebezpieczne. To tylko moja teoria!

W metodzie Dispose() nie trzeba umieszczać żadnego kodu niszczącego obiekt. Żeby nie zapomnieć o wywołaniu Dispose() gdy już nam obiekt nie jest potrzebny, można użyć pewnej sztuczki: konstrukcje obiektu umieścić w klauzuli using. Dzięki temu w chwili zakończenia jakiegoś bloku kodu, Dispose() zostanie wywołana automatycznie.</ort>

0

Dzieki za odpowiedz. Tez wlasnie nad taka teoria myslalem... Tylko to troche jest dziwne ze nie usuwa sie ta referencja do obiektu. No ale coz - pewnie to ma jakas swoja przyczyne ktora zrozumiem, jak bede madrzejszy.

C# to moj pierwszy jezyk - nie liczac pascala (ale to bylo tak tylko na informatyce w liceum jakies 7-8 lat temu) - potem zabralem sie za Delphi ale po 2 tygodniach plany sie nieco zmienily i musialem sie z pewnych powodow przesiasc na C#. Przygode z pascalem i delphi traktuje jako nauke podstaw w stylu petle, zmienne itd, ale jesli chodzi o bardziej zaawansowane rzeczy jak obiekty, dziedziczenie, delegacje, zdarzenia itp to pierwszy raz w zasadzie mialem z nimi kontakt w C#.

Korzystam z kilku ksiazek - przede wszystkim:

  • Programming C# - Jesse Liberty (moja ulubiona bo facet na prawde klarownie tlumaczy na przykladach - tyle tylko ze czasami odwoluje sie do C ktorego nie znam :)

  • Microsoft ADO.NET - David Sceppa. Tez calkiem przyzwoita ksiazka, jak sam tytul mowi do ADO.NET

  • Head First Design Patterns (edycja polska z helionu) - Jak w tytule o wzorcach projektowych. Ksiazka co prawda napisana dla Javy ale przyklady sa bardzo proste (kilkunasto linijkowe) i latwo je "przetlumaczyc" na C#, za to swietnie wylozona jest teoria wzorcow projektowych.

Bylo jeszcze kilka ksiazek ktore troche przegladalem, ale w zasadzie jeszcze chyba za slaby na nie jestem. Te trzy to dla mnie tak mala biblia teraz :)

0

Tajemnica Dispose jest to ze ono nic nie robi ;-). Naprawde. Tez mi bylo w to ciezko uwierzyc ale tak jest.
Tak wiec Dispose() jest po to aby zwalniac zasoby niezarzadzane (unamanged).
Zasoby niezarzadzane to takie jak (troche wymyslam, bo na razie nie pisalem pod .NET korzystajac jednoczesnie z czegos niezarzadzanego) : jakies polaczenia w sieci, polacznie z baza danych, jakas pamiec - ale tylko te ktore jakos dostalismy poza srodowieskiem .NET (CLR).
Tak wiec JESLI tworzymy klase ktora bedzie korzystac z jakis zasobow niezarzadzanyh (czyli poza CLR) to powinnismy zaimplementowac interfejs IDisposable (ktory glownie definiuje metode Dispose() i chyba niewiele wiecej).
W tej metodzie umieszczamy kod ktory zwolni te zasoby (zwolni pamiec, zamknie polaczenie TCP, czy cos). Teraz na programiscie ktory bedzie korzystal z naszej klasy spoczywa obowiazek wywolania tej metody po uzyciu naszego obiektu.
I co wazne: metoda Dispose() NIE jest automatycznie wywolywana przez destruktor obiektu. Czyli jesli programista zapomni wywolac Dispose chociaz musial, to te zasoby zewnetrzne nie beda zwolnione o ile nie zwolnimy ich w destruktorze.

Wazne jest to, ze Dispose ma sie nijak do obiektow zarzadzanych (managed) czyli obiektow ktore sa pod kontrola GC (odsmiecacza). Wywolanie czy nie Dispose na obiekcie w zaden sposob nie wplywa na dzialanie GC. Nie ma metody ktora by usunela obiekt natychmiast. Mozna wywolac GC.Collect() tyle ze ona AFAIR tez nie gwarantuje usuniecia obietkow.
Zwiazane jest to z tym ze odsmiecacz nie lubi usuwac obiektow duzych i takich ktorye maja zdefiniowany destruktor - bo jesli taki obiekt GC usuwa, to musi tenze destruktor wywolac, a on z kolei moze sie wykonywac dlugo. Dlatego usuniecie obiektow posiadajacych destruktor lub duzych jest odkladane na pozniej (na nastepne cykle odsmiecania).

Tutaj jest jakas dyskusja na temat Dispose() , ktora mi troche poomgla to zrozumiec:
http://weblogs.asp.net/pwilson/archive/2004/02/20/77435.aspx

Mam nadzieje, ze udalo mi sie wykazac, ze nie nalezy mylic Dispose() z delete z C++.

Pozdrawiam.

0

Smieszna sprawa, akurat dwa dni temu zabralem sie za ksiazke "C# and Net platform" (ktora szczerze polecam) i wczoraj okolo 23-24 znalazlem odpowiedz na to pytanie:-)
Nawet chcialem od razu odpisac, jakby ktos sie jeszcze nad tym zastanawial ale jakos juz mi sie nie chcialo i mialem zrobic to dzisiaj...

To co mowisz Artur w zasadzie zgadza sie z tym jak ja to zrozumialem. W sumie tylko jesci chodzi o metode Collect to z tego co ja zrozumialem, to obiekty maja trzy stany wedlug GC - 0, 1, 2 - Im starszy obiekt tym ma wyzszy stan. W pierwszej kolejnosci usowane sa obiekty ze stanem 0. Te ze stanem 2 jest bardzo prawdopodobne ze nie zostana usuniete az do konca dzialania programu (chyba ze wczesniej zabraknie pamieci).

I taka jeszcze rada dla rozpoczynajacych programowanie (w tym do mnie :) ) aby nie uzywac (jesli to tylko mozliwe) wlasnych destruktorow, gdyz to znacznie zmniejsza wydajnosc aplikacji.

Tajemnica Dispose jest to ze ono nic nie robi . Naprawde. Tez mi bylo w to ciezko uwierzyc ale tak jest.

Witaj w klubie :) [browar]

Wracam do lektury - cos czuje ze to nie ostatnie zaskoczenie :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1