Mi se cere să implementez ID-ul care poate fi pus pe resurse 100% gestionate, care nu conțin fluxuri și nu au resurse mari.

Înțeleg importanța eliminării corespunzătoare a resurselor mari și a resurselor neadministrate, dar ce se întâmplă cu cealaltă parte a ecuației?

Pentru un obiect care nu beneficiază de implementarea IDisposable (obiecte mici complet gestionate) , ce impact negativ poate avea GC.SuppressFinalize, dacă există?

Comentarii

  • Pare o optimizare prematură. Sunteți în măsură să întrebați persoana care v-a cerut să obțineți rezultatele obținute de la profilare și comparare, care arată că adăugarea IDisposable în acest caz îmbunătățește amprenta memoriei?
  • @MainMa Nu, dar asta nu ' m-a împiedicat să întreb oricum. Rezultatul a fost un răspuns de 5 minute de " este exact așa cum am făcut-o întotdeauna ', și tu ".
  • Ei bine, este posibil să implementați IDisposable fără a scrie un destructor / finalizator. Nu ' nu știu dacă persoana care v-a cerut să implementați IDisposable a însemnat că ar trebui să faceți și un distructor. Desigur, dacă clasa nu are destructor, nu are niciun punct în GC.SuppressFinalize. Dacă clasa are un destructor, asigurați-vă că spuneți GC.SuppressFinalize(this) când metoda dvs. Dispose a rulat. În caz contrar, instanța nu va fi colectată cu ușurință, va fi pusă în coadă pe o coadă de finalizare și va fi colectată doar într-o colecție de generația 2.
  • @JeppeStigNielsen Întrebarea se afirmă că obiectele se ocupă cu gestionarea completă resurse, deci nu este necesar ' să aveți un finalizator. Dacă cineva este acolo, știm că ' este greșit.

Răspuns

Singurul obiectiv al GC.SuppressFinalize este:

pentru a împiedica finalizatorul să elibereze resurse neadministrate care au fost deja eliberați de IDisposable.Dispose implementarea.

Sursa: MSDN

Odată ce ați eliminat obiectul, ar trebui să apelați într-adevăr GC.SuppressFinalize(this);, așa cum se arată în un răspuns la întrebarea ” Când ar trebui să folosesc GC.SuppressFinalize ()? „. Analiza codului „ regula CA1816 este de asemenea utilă.

Acum, implementarea IDisposable pe obiectele care nu au resurse necontrolate par destul de ciudate și discutabile. Deoarece singurul motiv pe care ți l-a dat persoana a fost: „așa cum am făcut-o întotdeauna, o faci și tu”, în loc să oferi date de profilare / comparare care arată că adăugarea IDisposable va îmbunătăți ceva într-un caz specific, nu există motive reale pentru a face acest lucru.

Ar provoca probleme de performanță? Greu de spus: ar depinde de un anumit caz.

cauzează alte probleme? Desigur. Fără a lua în considerare faptul că IDisposable este dureros de implementat, dacă această practică este folosită prea mult, codul devine ilizibil și imposibil de întreținut:

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

Comentarii

  • Ei bine, cred că povestea este că, cu mult timp în urmă, aveau o oarecare legătură / probleme legate de scurgeri de flux, probabil din cauza conexiunii scurte / a codului ADO.NET de comandă, iar acest lucru a provocat scurgeri masive de resurse. Știau că implementarea IDisposable pe tot va rezolva problema, așa că au făcut-o și a funcționat. trebuie să îl implementați pe majoritatea obiectelor.
  • @AndrewHoffman: pare o explicație plauzibilă. Dar încă nu ' nu justifică practica curentă.

Răspuns

Nu trebuie să utilizați modelul Dispose + Finalizer pentru greutate mare („dureros”) pe o clasă IDisposable, dacă clasa este sigilată, iar clasa nu are resurse neadministrate.

În această situație, puteți utiliza un subset al modelului Dispose + Finalizer, care are doar Dispose(), nu are finalizator, iar clasa este sigilată.

Motivul sigilării clasei este de a evita problemele „Ce se întâmplă dacă o clasă copil are resurse neadministrate?” și „Ce se întâmplă dacă o clasă de copii în viitor va avea resurse neadministrate?”

Joe Duffy, fost Microsoft, are un articol lung (peste 30 de pagini) care discută despre cum să implementați corect IDisposable și toate implementările de subset de permutare.

Contribuitorii la articol includ Herb Sutter, Brian Grunkemeyer, Jeff Richter și alți corpuri de iluminat C #. Articolul este mult mai aprofundat decât ceea ce este prezentat pe MSDN.

Din păcate, noul motor de blog al lui Joe Duffy nu a făcut o treabă bună de conservare a articolului original din 2005, așa că pare oarecum înțeles. / div> http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/

Mi-aș dori să pot atașa documentul MS-Word care conține întregul articol al lui Joe Duffy într-un text mult mai bun format. 🙁

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *