Megkérnek az IDisposable megvalósítására olyan objektumokon, amelyek 100% -ban kezelt erőforrások, amelyek nem tartalmaznak patakokat és nem tartalmaznak nagy erőforrásokat.
Megértem a nagy erőforrások és a nem kezelt erőforrások megfelelő ártalmatlanításának fontosságát, de mi a helyzet az egyenlet másik oldalával?
Olyan objektum esetében, amelynek nem előnyös az IDisposable (kicsi, teljesen felügyelt objektumok) megvalósítása , milyen negatív hatása lehet a GC.SuppressFinalize-nak, ha van ilyen?
Megjegyzések
Válasz
A GC.SuppressFinalize
egyetlen célja:
megakadályozni, hogy a véglegesítő olyan felügyelet nélküli erőforrásokat szabadítson fel, amelyek már felszabadította az IDisposable.Dispose megvalósítás.
Miután megsemmisítette az objektumot, valóban meg kell hívnia a GC.SuppressFinalize(this);
-t, amint az a részben is látható. ” Mikor használjam a GC.SuppressFinalize () -t? “. A “ CA1816 szabály elemzése szintén hasznos.
Most a IDisposable
megvalósítását olyan tárgyak, amelyeknek nincsenek kezeletlen erőforrásai, elég furcsának és kérdésesnek tűnnek. Mivel az egyetlen ok, amiért ezt a személy megadta neked, a következő volt: “csak úgy, ahogy mi mindig csináltuk, te is csinálod”, ahelyett, hogy profilozási / benchmarking adatokat szolgáltatna, ami azt mutatja, hogy a IDisposable
javít valamit egy adott esetben, nincs tényleges oka annak.
Teljesítményproblémákat okozna? Nehéz azt mondani: ez konkrét esettől függ.
egyéb problémákat okoz? Természetesen. Nem számítva azt a tényt, hogy IDisposable
fájdalmas végrehajtani, ha ezt a gyakorlatot túlságosan alkalmazzák, a kód olvashatatlanná válik, és fenntartása lehetetlenné válik:
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; } } } } }
Megjegyzések
- Nos, azt hiszem, a történet az, hogy nagyon régen volt valamilyen kapcsolatuk / szivárgó problémákat streamelhet, valószínűleg a szivárgó kapcsolat / parancs ADO.NET kód miatt, és ez hatalmas erőforrásszivárgást okozott. Tudták, hogy az IDisposable mindenre telepítése megoldja a problémát, így is sikerült, és ez működött. És most ezért j végre kell hajtania a legtöbb objektumon.
- @AndrewHoffman: hihető magyarázatnak tűnik. De még mindig nem igazolja a jelenlegi gyakorlatot '.
Válasz
Nem kell a nehézsúlyú (“fájdalmas”) Hulladék + véglegesítő mintát használni egy IDisposable osztályban, ha osztály le van zárva, és az osztálynak nincsenek nem felügyelt erőforrásai.
Ebben a helyzetben használhatja a Dispose + Finalizer minta egy részhalmazát, amelynek éppen nyilvános Dispose()
, nincs véglegesítője, és az osztály le van zárva.
Az osztály lezárásának oka az, hogy elkerülje a „Mi van, ha a gyermek osztálynak nincsenek kezelt erőforrásai?” problémákat. és “Mi van, ha a jövőben egy gyermekosztálynak nem lesz kezelt erőforrása?”
Joe Duffy, korábban a Microsoft munkatársa, egy hosszú (30+ oldalas) cikket tartalmaz, amely a és az összes permutációs részhalmaz megvalósítása.
A cikk közreműködői között szerepel Herb Sutter, Brian Grunkemeyer, Jeff Richter és más C # világítótestek. A cikk sokkal mélyebb, mint az MSDN-en.
Sajnos, Joe Duffy új blogmotorja nem végzett jó munkát az eredeti 2005-ös cikk megőrzésében, ezért kissé elgondolkodva néz ki. Itt van a link: http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/
Szeretném sokkal jobbra csatolni az MS-Word dokumentumomat, amely Joe Duffy teljes cikkét tartalmazza formátum. 🙁
IDisposable
hozzáadása ebben az esetben javítja a memória lábnyomát?IDisposable
megvalósítása pusztító / véglegesítő írása nélkül. Nem tudom, hogy ' nem tudom, hogy az a személy, aki felkérte, hogy hajtsa végre aIDisposable
alkalmazást, azt is értette, hogy készítsen-e rombolót is. Természetesen, ha az osztálynak nincs destruktora, akkor nincs értelme aGC.SuppressFinalize
-nek. Ha az osztálynak van destruktora, akkor mindenképpen mondja ki aGC.SuppressFinalize(this)
szót, amikor aDispose
metódusa lefutott. Ellenkező esetben a példány nem lesz könnyen szemétgyűjtő, hanem egy véglegesítő sorba kerül, és csak egy 2. generációs gyűjtőben gyűlik össze.