Jeg bliver bedt om at implementere IDisposable på objekter, der er 100% administrerede ressourcer, der ikke indeholder nogen streams og ingen store ressourcer.

Jeg forstår vigtigheden af korrekt bortskaffelse af store ressourcer og ikke-administrerede ressourcer, men hvad med den anden side af ligningen?

For et objekt, der ikke har gavn af at implementere IDisposable (små fuldt administrerede objekter) , hvilken negativ indvirkning kan GC.SuppressFinalize have, hvis nogen?

Kommentarer

  • Ser ud som for tidlig optimering. Er du i stand til at bede den person, der bad dig om at gøre det, de resultater, han fik af profilering og benchmarking, der viser, at tilføjelse af IDisposable i dette tilfælde forbedrer hukommelsesfodaftryk?
  • @MainMa Nej, men det stoppede ikke ' mig fra at spørge alligevel. Resultatet var et svar på 5 minutter på " det er netop sådan, som vi ' altid har gjort det, du gør det også ".
  • Nå, det er muligt at implementere IDisposable uden at skrive en destruktor / finalizer. Jeg ved ikke ' om den person, der bad dig om at implementere IDisposable, mente at du også skulle gøre en destruktør. Selvfølgelig, hvis klassen ikke har nogen destruktor, er der ingen mening i GC.SuppressFinalize. Hvis klassen har en destruktor, skal du sørge for at sige GC.SuppressFinalize(this) når din Dispose -metode er kørt. Ellers bliver forekomsten ikke let indsamlet skrald, den vil stå i kø i en finalizer-kø og kun indsamles i en generation-2-indsamling.
  • @JeppeStigNielsen Spørgsmålet siger, at objekterne har at gøre med fuldstændig administreret ressourcer, så ' behøver ikke at have en finalizer. Hvis man er der, ved vi det ' er forkert.

Svar

Det eneste mål for GC.SuppressFinalize er:

for at forhindre, at finalisatoren frigiver uhåndterede ressourcer, der er allerede blevet frigivet af IDisposable.Dispose implementering.

Kilde: MSDN

Når du har bortskaffet objektet, skal du faktisk kalde GC.SuppressFinalize(this);, som vist i et svar på spørgsmålet ” Hvornår skal jeg bruge GC.SuppressFinalize ()? “. Kodeanalyse “ CA1816 -reglen er også nyttig.

Nu implementeres IDisposable på objekter, der ikke har ikke-administrerede ressourcer, ser ret underlige og tvivlsomme ud. Da den eneste grund til, at personen gav dig, var: “det er bare den måde, vi” altid har gjort det, gør du det også “i stedet for at levere profilerings- / benchmarkingdata, der viser, at tilføjelse af IDisposable vil forbedre noget i en bestemt sag, der er ingen faktiske grunde til at gøre det.

Ville det medføre ydeevneproblemer? Vanskeligt at sige: det ville afhænge af en bestemt sag.

Ville Det medfører andre problemer? Selvfølgelig. Tæller ikke det faktum, at IDisposable er smertefuldt at implementere, hvis denne praksis bruges for meget, bliver koden uleselig og umulig at vedligeholde:

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

  • Nå, jeg tror historien er, at de for længe siden havde en vis forbindelse / stream lækage problemer, sandsynligvis på grund af utæt forbindelse / kommando ADO.NET kode, og dette forårsagede massive ressource lækager. De vidste, at implementering af IDisposable på alt ville løse problemet, så de gjorde det, og det fungerede. Og så nu j de bare implementer det på de fleste objekter.
  • @AndrewHoffman: det virker som en plausibel forklaring. Men det berettiger stadig ikke ' t den nuværende praksis.

Svar

Du behøver ikke bruge det tunge (“smertefulde”) bortskaffelses- + finaliseringsmønster på en ID-disponibel klasse, hvis klassen er forseglet, og klassen har ingen ikke-administrerede ressourcer.

I den situation kan du bruge en delmængde af Dispose + Finalizer-mønsteret, som bare har offentlig Dispose(), har ingen finalizer, og klassen er forseglet.

Årsagen til at forsegle klassen er at undgå problemerne med “Hvad hvis en barneklasse har ikke-administrerede ressourcer?” og “Hvad hvis en underordnet klasse i fremtiden vil have ikke-administrerede ressourcer?”

Joe Duffy, tidligere Microsoft, har en lang artikel (30+ sider), der diskuterer, hvordan man korrekt implementerer IDisposable og alle permutationsimplementeringsimplementeringer.

Bidragydere til artiklen inkluderer Herb Sutter, Brian Grunkemeyer, Jeff Richter og andre C # -armaturer. Artiklen er meget mere dybtgående end hvad der præsenteres på MSDN.

Ak, Joe Duffys nye blogmotor har ikke gjort et godt stykke arbejde med at bevare den originale artikel fra 2005, så den ser noget munged ud. Her er linket: http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/

Jeg ville ønske, at jeg kunne vedhæfte mit MS-Word-dokument, der har hele Joe Duffys artikel i en meget bedre format. 🙁

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *