Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Nejasnoca u vezi dispose/finalize patterna

[es] :: .NET :: Nejasnoca u vezi dispose/finalize patterna

[ Pregleda: 1846 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

_v!rus_
BGD

Član broj: 40451
Poruke: 313
*.dsl.siol.net.



+1 Profil

icon Nejasnoca u vezi dispose/finalize patterna24.06.2007. u 20:09 - pre 205 meseci
Na MSDN-u je ovaj primer za tipican/najbolji dispose design pattern, ocistio sam samo suvisne komentare:
Code:

public class BaseResource: IDisposable
{
   // Pointer to an external unmanaged resource.
   private IntPtr handle;
   // Other managed resource this class uses.
   private Component Components;
   private bool disposed = false;

   public BaseResource()
   {
      // Insert appropriate constructor code here.
   }

   public void Dispose()
   {
      Dispose(true);
      GC.SuppressFinalize(this);
   }

   protected virtual void Dispose(bool disposing)
   {
      if(!this.disposed)
      {
         if(disposing)
         {
            // Dispose managed resources.
            Components.Dispose();
         }
         CloseHandle(handle);
         handle = IntPtr.Zero;
      }
      disposed = true;         
   }

   // Use C# destructor syntax for finalization code.
   // This destructor will run only if the Dispose method 
   // does not get called.
   // It gives your base class the opportunity to finalize.
   ~BaseResource()      
   {
      // Do not re-create Dispose clean-up code here.
      // Calling Dispose(false) is optimal in terms of
      // readability and maintainability.
      Dispose(false);
   }

   // Allow your Dispose method to be called multiple times,
   // but throw an exception if the object has been disposed.
   // Whenever you do something with this class, 
   // check to see if it has been disposed.
   public void DoSomething()
   {
      if(this.disposed)
      {
         throw new ObjectDisposedException();
      }
   }
}



Moje pitanja su

1. Sta ce se desiti sa unmanaged resursima kada GC finalizira objekat? Iz koda se vidi da ce se pozvati Dispose(false), i taj "false" ce zaobici granu koja oslobadja unmanaged resurse... Zasto se u finalizeru ne poziva Dispose(true). Neko bi mozda rekao "pa zato sto mozda drugi objekti koriste umanaged resurse koje je ovaj objekat kreirao/otvorio, cim ti nisi explicitno pozvao dispose GC ih ne dira", ali onda cleanup kod za takve shared non-managed resurse ne bi ni trebao da bude u Dispose metodi, cak stavise ne bi ni trebao da se kreira od strane tog objekta...

2. Zasto se onaj bool parametar zove "disposing"? Od MS-a sam navikao na skolska deskriptivna imena varijabli, ime tog parametra u odnosu na njegovu svrhu nema nikakvog smisla, ili ga ja ne vidim (prvo bi pomislio na osnovu imena da je to neki thread-safety parametar)

3. Komentar iznad destruktora kaze "This destructor will run only if the Dispose method does not get called."
Jel su time mislili na disposing kontrolnu varijablu koja se setuje posle Dispose poziva (u tom slucaju komentar nije tacan, jer ce se onda destruktor ipak izvrsiti, samo ce uleteti u Dispose gde nece uraditi nista zbog kontrolne varijable). Ili su mozda mislili da .net framework nece pozvati destruktor uopste, ako si ti negde vec pozvao Dispose (u tom slucaju bi jezik bio nekako vezan na ime metode sto mi se cini malo verovatno, ako i jeste onda je to idiotski reseno, isto kao i hard-coded vezivanje operatora "yield" za IEnumerator interfejs, i jos mnogo hardkodovanih .net gluposti)

EDIT: Tek sada sam video onaj GC.SupressFinalize, tako da je odgovor na #3 u sustini jasan...

[Ovu poruku je menjao _v!rus_ dana 24.06.2007. u 21:21 GMT+1]

[Ovu poruku je menjao _v!rus_ dana 25.06.2007. u 13:21 GMT+1]
 
Odgovor na temu

dusty
Predrag Glumac
Zemun, Srbija

Član broj: 15383
Poruke: 549
*.ptt.yu.

Sajt: www.mika.rs


+6 Profil

icon Re: Nejasnoca u vezi dispose/finalize patterna25.06.2007. u 08:25 - pre 205 meseci
1. Managed objekte je GC vec pocistitio, kad tad, koristeci mehanizam sa generacijama. A zasto se ne poziva u destruktoru Dispose(true) ? Zato sto se desktruktor (tj. finalizer) poziva kada tek kada svi managed objekt koji pripadaju instanci koja je na disposing queue-u pociste (zapravo zbog destruktora je u finalization queue-u), i ostanu samo unmanaged objekti, koje GC kao sto znas ne moze da prati.

2. Jer su tako u mogucnosti Shalim se, jedino sto mi pada na pamet je zato sto ako se Dispose poziva iz destruktora, onda nije disposing nego finalization ..... malko shuplja prica
America national sport is called baseballs. It very similar to our sport, shurik, where we take dogs, shoot them in a field and then have a party.
 
Odgovor na temu

_v!rus_
BGD

Član broj: 40451
Poruke: 313
*.dsl.siol.net.



+1 Profil

icon Re: Nejasnoca u vezi dispose/finalize patterna25.06.2007. u 12:21 - pre 205 meseci
Citat:

Managed objekte je GC vec pocistitio...


Moj typo, mislio sam:
1. Sta ce se desiti sa unmanaged resursima...

Bio sam toliko zbunjen da nisam znao ni sta pisem... :) Anyway popravio sam post.
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Nejasnoca u vezi dispose/finalize patterna25.06.2007. u 13:23 - pre 205 meseci
1. Stvar je u pretpostavkama (kojih vala ima previse). Ako ti pozoves dispose() pretpostavlja se da si "vlasnik" svih unmanaged resursa u tvojoj klasi kao i svih unmanaged resursa u klasama koje si instancirao i ubacio u svoju Components kolekciju. Components.Dispose() onda ocisti te child unmanaged resurse jer pretpostavlja da znas sta radis . Iz tog razloga nije bas pametno koristiti npr sqlconnection iz drugog forma, niakd ne znas dal' ce pasti neki dispose()

Ako ti nisi pozvao Dispose(), pattern se prebacuje u "don't touch" mode i pri finalizaciji unistava samo svoje unmanaged resurse. Teorija je da ako komponenete u components ne postoje nigde drugo onda ce GC da flaguje i te objekte za finalization kad markira parent objekat, pa ce njihovi finilizeri da ociste svoje unamanged resurse i tako rekurzivno dok ima objekata ili steka . Ako je child objekat referenciran jos negde onda nece biti flagovan i njegovi unmanged resursi ce ziveti.

2. "disposing" kao "disposing entire object tree"


Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

_v!rus_
BGD

Član broj: 40451
Poruke: 313
*.dsl.siol.net.



+1 Profil

icon Re: Nejasnoca u vezi dispose/finalize patterna25.06.2007. u 13:52 - pre 205 meseci
Citat:

Ako je child objekat referenciran jos negde onda nece biti flagovan i njegovi unmanged resursi ce ziveti


E, to je bio "missing link" Nikako da svarim da Dispose ne znaci nista u smislu oslobadjanja memorije...
Sad mi je jasno, automatski dispose (onaj koji je GC pozvao indirektono, preko destruktora) nece uraditi nista ako se nested objekti jos koriste negde drugde, managed resurse nece dirati uopste.

Znaci taj "design pattern" ni u kom slucaju nece osloboditi eventualne non-managed resurse, ako ti rucno ne pozoves dispose.
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Nejasnoca u vezi dispose/finalize patterna25.06.2007. u 14:52 - pre 204 meseci
pa ne bas, prvi deo ti je ok, drugi nije; "automatski" kako ga ti zoves, dispose(false) nece dirati un-managed resurse svoje "dece", ali ce i te kako da oslobodi svoje licne un-managed resurse. Ako je doslo do toga da finalizer mora da cisti unmanaged resurse onda nema mnogo razlike da li ces ti pozvati dispose nad decom ili ne, ako si pravilno programirao u skladu sa MS preporukama, sva deca ce biti finalizovana takodje.

U svakom slucaju ce unmanaged resurs biti oslobodjen pre ili kasnije, ali je bolje rucno uraditi dispose() da bi se taj unmanaged resurs koji je obicno skup i u ogranicenim kolicinama mogao mogao ponovo iskoristiti. realno moze da se desi da finalizer ne bude pozvan danima ili mesecima u npr windows servisima i da sve to vreme drzi neki skup unmanaged resurs. generalno govoreci, oslanjanje na finalizer je losa programerska praksa, em drzi resurse duze nego sto treba, em usporava GC cleanup.

imaj takodje u vidu da je dispose(true/false) patern MSova budzevina nad dispose paternom, pravi patern nema razliku izmedju automatskog i rucnog, postoji samo jedan dispose() metod u kome se oslobadjaju resursi i finalizer poziva njega direktno. da bi resili problem sa oslobadjanjem unmanaged resursa u komponentama formi i ostalih "dizajnerskih" kontejnera osmislise ovo. Nije savrseno, ali dok god ne koristis dataset iz jedne forme u drugoj dobar si.
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

[es] :: .NET :: Nejasnoca u vezi dispose/finalize patterna

[ Pregleda: 1846 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.