Jeg blir bedt om å implementere IDisposable på objekter som er 100% administrerte ressurser, som ikke inneholder strømmer og ingen store ressurser.

Jeg forstår viktigheten av å disponere store ressurser og ikke-administrerte ressurser på riktig måte, men hva med den andre siden av ligningen?

For et objekt som ikke har nytte av å implementere IDisposable (små fullt administrerte objekter) , hvilken negativ innvirkning kan GC.SuppressFinalize ha, hvis noen?

Kommentarer

  • Ser ut som for tidlig optimalisering. Er du i stand til å be personen som ba deg om å gjøre at resultatene han fikk av profilering og benchmarking som viser at å legge til IDisposable i dette tilfellet forbedrer minnefotavtrykket?
  • @MainMa Nei, men det hindret meg ikke '. Resultatet var et 5-minutters svar på " det er akkurat slik vi ' alltid har gjort det, du gjør det også ".
  • Vel, det er mulig å implementere IDisposable uten å skrive en destruktor / finalizer. Jeg vet ikke ' om personen som ba deg implementere IDisposable mente at du også skulle lage en destruktør. Selvfølgelig, hvis klassen ikke har noen ødelegger, er det ingen vits i GC.SuppressFinalize. Hvis klassen har en destruktør, må du si GC.SuppressFinalize(this) når Dispose -metoden din har kjørt. Ellers vil ikke forekomsten lett bli samlet inn søppel, den vil stå i kø i en finalizer-kø og bare bli samlet i en generasjon-2-samling.
  • @JeppeStigNielsen Spørsmålet sier at objektene har å gjøre med fullstendig administrert ressurser, så ' trenger ikke å ha en finalizer. Hvis en er der, vet vi at den ' er feil.

Svar

Det eneste målet med GC.SuppressFinalize er:

for å forhindre at sluttbehandleren frigjør uhåndterte ressurser som har allerede blitt frigjort av IDisposable.Dispose implementering.

Kilde: MSDN

Når du har disponert objektet, bør du faktisk kalle GC.SuppressFinalize(this);, som vist i et svar på spørsmålet » Når skal jeg bruke GC.SuppressFinalize ()? «. Kodeanalyse « CA1816 -regelen er også nyttig.

Nå implementerer du IDisposable på gjenstander som ikke har ubehandlede ressurser, ser ganske rare og tvilsomme ut. Siden den eneste grunnen til at personen ga deg var: «det er akkurat slik vi alltid har gjort det, du gjør det også», i stedet for å gi profilerings- / benchmarkingdata som viser at å legge til IDisposable vil forbedre noe i et bestemt tilfelle, det er ingen faktiske grunner til å gjøre det.

Ville det forårsake ytelsesproblemer? Vanskelig å si: det vil avhenge av en bestemt sak.

Ville det forårsaker andre problemer? Selvfølgelig. Teller ikke det faktum at IDisposable er smertefullt å implementere, hvis denne fremgangsmåten brukes for mye, blir koden uleselig og umulig å opprettholde:

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; } } } } } 

Kommentarer

  • Vel, jeg tror historien er at for lenge siden hadde de en viss forbindelse / strømlekkingsproblemer, sannsynligvis på grunn av utett tilkobling / kommando ADO.NET-kode, og dette forårsaket enorme ressurlekkasjer. De visste at implementering av IDisposable på alt ville løse problemet, så de gjorde det, og det fungerte. Og så nå j bare implementer det på de fleste objekter.
  • @AndrewHoffman: det virker som en sannsynlig forklaring. Men det rettferdiggjør fortsatt ikke ' t dagens praksis.

Svar

Du trenger ikke å bruke det tunge («smertefulle») avhending + finaliseringsmønsteret på en ID-disponibel klasse, hvis klassen er forseglet, og klassen har ingen uadministrerte ressurser.

I den situasjonen kan du bruke en delmengde av Dispose + Finalizer-mønsteret, som bare har offentlig Dispose(), har ingen sluttbehandler, og klassen er forseglet.

Årsaken til å forsegle klassen er å unngå problemene med «Hva om en barneklasse har uadministrerte ressurser?» og «Hva om en barneklasse i fremtiden vil ha uadministrerte ressurser?»

Joe Duffy, tidligere Microsoft, har en lang (30+ sider) artikkel som diskuterer hvordan du korrekt implementerer IDisposable, og alle permutasjonsundersettingsimplementeringene.

Bidragsytere til artikkelen inkluderer Herb Sutter, Brian Grunkemeyer, Jeff Richter og andre C # -armaturer. Artikkelen er mye mer inngående enn det som presenteres på MSDN.

Akk, Joe Duffys nye bloggmotor har ikke gjort en god jobb med å bevare den opprinnelige artikkelen fra 2005, så den ser noe stukket ut. Her er lenken: http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/

Jeg skulle ønske jeg kunne legge ved MS-Word-dokumentet mitt som har hele Joe Duffys artikkel i en mye bedre format. 🙁

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *