Jsem požádán o implementaci IDisposable na objekty, které jsou 100% spravovanými prostředky, které neobsahují žádné streamy a žádné velké zdroje.

Chápu důležitost správného nakládání s velkými a nespravovanými prostředky, ale co na druhou stranu rovnice?

Pro objekt, který nemá prospěch z implementace IDisposable (malé plně spravované objekty) , jaký negativní dopad může mít GC.SuppressFinalize, pokud existuje?

Komentáře

  • Vypadá to jako předčasná optimalizace. Máte možnost požádat osobu, která vás o to požádala, aby výsledky, které získal z profilování a srovnávání, které ukazují, že přidání IDisposable v tomto případě zlepšuje paměťovou stopu?
  • @MainMa Ne, ale to mi ' nezabránilo v žádném případě. Výsledkem byla 5minutová odezva " tak, jak jsme to vždy ' udělali, uděláte to taky ".
  • Je možné implementovat IDisposable bez psaní destruktoru / finalizátoru. Nevím ' nevím, jestli osoba, která vás požádala o implementaci IDisposable, měla v úmyslu udělat také destruktor. Samozřejmě, pokud třída nemá destruktor, nemá v GC.SuppressFinalize smysl. Pokud třída má destruktor, nezapomeňte říci GC.SuppressFinalize(this), když je metoda Dispose spuštěna. V opačném případě nebude instance snadno shromažďována odpadky, bude zařazena do fronty finalizační fronty a bude shromažďována pouze ve shromažďování generace 2.
  • @JeppeStigNielsen Otázka uvádí, že objekty se zabývají zcela spravovanou zdroje, takže ' není třeba mít finalizátor. Pokud tam někdo je, víme, že je ' špatně.

Odpovědět

Jediným cílem GC.SuppressFinalize je:

zabránit finalizátoru uvolnit nespravované zdroje, které již byly uvolněny implementací IDisposable.Dispose.

Zdroj: MSDN

Jakmile objekt zlikvidujete, měli byste skutečně zavolat GC.SuppressFinalize(this);, jak je uvedeno v odpovědi na otázku “ Kdy mám použít GC.SuppressFinalize ()? „. Užitečná je také analýza kódu „ CA1816 pravidlo.

Nyní implementujeme IDisposable na objekty, které nemají nespravované zdroje, vypadají docela divně a pochybně. Protože jediným důvodem, který vám daná osoba dala, bylo: „je to tak, jak jsme to vždy udělali my, uděláte to taky“, místo poskytnutí profilovacích / srovnávacích údajů, které ukazují, že přidání IDisposable vylepší něco v konkrétním případě, nejsou k tomu skutečné důvody.

Způsobilo by to problémy s výkonem? Těžko říci: záleželo by to na konkrétním případě.

způsobí to další problémy? Samozřejmě. Nepočítáme-li skutečnost, že implementace IDisposable je bolestivá, pokud je tato praxe příliš používána, kód se stává nečitelným a nelze jej udržovat:

public int ComputePrice(Rebate rebate) { using (var currentCurrency = this.User.FindCurrency()) { using (var priceWithoutRebate = this.GetPurePrice()) { using (var canApplyRebate = rebate.CanApplyTo(this)) { if (!canApplyRebate) { return priceWithoutRebate; } using (var priceWithRebate = priceWithoutRebate.Apply(rebate)) { return priceWithRebate; } } } } } 

Komentáře

  • Věřím, že příběh je takový, že už dávno měli nějaké spojení / problémy s únikem proudu, pravděpodobně kvůli netěsnému připojení / příkazu kódu ADO.NET, a to způsobilo obrovské úniky zdrojů. Věděli, že implementace IDisposable na všem by problém vyřešila, a tak to udělali, a fungovalo to. proveďte to na většině objektů.
  • @AndrewHoffman: vypadá to jako věrohodné vysvětlení. Stále to ale ' neodůvodňuje současnou praxi.

Odpověď

U třídy IDisposable nemusíte používat vzor těžké váhy („bolestivý“) Dispose + Finalizer, if třída je zapečetěna a třída nemá žádné nespravované prostředky.

V této situaci můžete použít podmnožinu vzoru Dispose + Finalizer, který má pouze public Dispose(), nemá finalizátor a třída je zapečetěna.

Důvodem pro utěsnění třídy je vyhnout se problémům „Co když má podřízená třída nespravované prostředky?“ a „Co když podřízená třída v budoucnu bude mít nespravované prostředky?“

Joe Duffy, dříve Microsoft, má zdlouhavý (více než 30 stránek) článek, který pojednává o tom, jak správně implementovat IDisposable a všechny implementace podmnožiny permutace.

Přispěvateli do článku jsou Herb Sutter, Brian Grunkemeyer, Jeff Richter a další lumináři C #. Tento článek je mnohem podrobnější než to, co je uvedeno na MSDN.

Bohužel, nový blogovací modul Joe Duffyho neudělal dobrou práci při zachování původního článku z roku 2005, takže vypadá poněkud zpackaně. Zde je odkaz: http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/

Přeji si, abych mohl připojit svůj dokument MS-Word, který má celý článek Joe Duffyho, mnohem lépe formát. 🙁

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *