Naučit se PHP Naučit se PHP
Pouze tento týden až 80 % sleva na vývoj webů v PHP.
Extra 10 % bodů navíc a tričko zdarma při zadání kódu "TRIKO10"

Diskuze: Jednoduchý dotaz na dispose

C# .NET .NET (C# a Visual Basic) Jednoduchý dotaz na dispose American English version English version

Aktivity (3)
Avatar
Luboš Hnědý:23.11.2018 15:17

Ahoj, mám celkem jednoduchý dotaz. Dělám v .net mvc a dělám si vlastní třídu pro práci s emailem. Chci se zeptat zda mám implementovat metodu Dispose. Prostě když si vytvořím objekt, tak chci po použití ho zahodit, abych nezahlcoval tu paměť. Co je správný přístup? Mám to nějak řešit? Napadá mě právě zavolat metodu Dispose a v ní mít todle GC.SuppressFi­nalize(this); to by mělo jako ten objekt odstranit ne? Todle si jenom myslím! Má to vůbec smysl, já přesně nevím jak to funguje.... Předem děkuju :)

Zkusil jsem: Hledat na googlu ale našel jsem třeba jenom použití u souborů a u db, kde chápu k čemu to je otevření souboru atd...

Chci docílit: Správné funkčnosti

 
Odpovědět 23.11.2018 15:17
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Luboš Hnědý
Martin Petrovaj:23.11.2018 15:23

IDisposable implementuješ na tých objektoch, ktoré spravujú tzv. unmanaged resources (najčastejšie to sú spojenia k súborom, prípadne ak z aplikácie spúšťaš unmanaged (non-.net) kód).

GC.SuppressFinalize by si v 99.9999999999% pripadov nemal mať dôvod volať a už vôbec ho nemáš čo používať v Dispose. Keď už, tak sa táto metóda volá v deštruktore ( ~MenoTriedy() { } ), nie v Dispose.

https://docs.microsoft.com/…ting-dispose
https://docs.microsoft.com/…/destructors

Nahoru Odpovědět 23.11.2018 15:23
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Martin Petrovaj
Luboš Hnědý:23.11.2018 15:37

Dobře díky za vysvětlení. No a to je tedy jedno, že si vytvořím objekt a pak zůstane prostě v paměti? Nebo ho mám dát do DI?

 
Nahoru Odpovědět 23.11.2018 15:37
Avatar
Odpovídá na Martin Petrovaj
Luboš Hnědý:23.11.2018 15:42

Nebo se o to postará GC?

 
Nahoru Odpovědět 23.11.2018 15:42
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Luboš Hnědý
Martin Petrovaj:23.11.2018 15:47

GC sám uvoľnuje objekty v pamäti, na ktoré už nič neodkazuje. Neuvoľňuje jedine vyššie spomínané unmanaged resources. Musel by si mať veľmi, veľmi fucked up memory management, aby si GC nevedel robiť svoju prácu :-) Tam už je ale problém inde a implementovaním IDisposable ho nevyriešiš.

Btw, garbage collection a IDisposable nefungujú od seba oddelene, je chybou na to takto pozerať. V Dispose uvoľníš práve tie unmanaged resources, ktoré tvoj objekt spravuje, ale objekt samotný musí aj tak odpratať GC.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět  +1 23.11.2018 15:47
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Martin Petrovaj
Luboš Hnědý:23.11.2018 15:55

Jo aha to jsem neveděl :o Tak super děkuju moc fakt zajímavý! Tak děkuju moc jsem rád, že konečně vím jak to funguje. :)

 
Nahoru Odpovědět 23.11.2018 15:55
Avatar
Odpovídá na Martin Petrovaj
Luboš Hnědý:23.11.2018 20:56

Ještě jeden rychlý dotaz. Nemám si to tedy dát do toho DI? Já v tom prostě nevidím žádnou velkou výhodu, až na to že komunikuji vlastně s rozhraním a ne se třídou což je fajn, ale jinak nevím.... Předem diky za objasnění

 
Nahoru Odpovědět 23.11.2018 20:56
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Luboš Hnědý
Martin Petrovaj:23.11.2018 21:00

To by si mal vedieť sám. Ja tvoj projekt nepoznám, takže do veľkej miery si budem teraz cucať z prsta. Ale áno, objekt pre prácu s emailom znie ako niečo, čo chceš naprieč aplikáciou zdieľať cez DI.

Veď ty počkaj až budeš niekedy ten systém upravovať alebo naňho písať testy, bleskovo zistíš, načo ti tie rozhrania sú :-D

Nahoru Odpovědět  +1 23.11.2018 21:00
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Odpovídá na Martin Petrovaj
Luboš Hnědý:24.11.2018 21:36

A můžu nějak použít v DI objekt s kontruktorem? Nebo to musím udělat přes vlastnosti?

Editováno 24.11.2018 21:37
 
Nahoru Odpovědět 24.11.2018 21:36
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Luboš Hnědý
Martin Petrovaj:24.11.2018 21:52

Mal by si sa vyhýbať tomu, aby tvoje objekty určené pre DI mali parametrizované konštruktory (ak správne chápem tvoj problém, tak ťa trápi, či môže mať tvoj objekt konštruktor s parametrami. Bezparametrický konštruktor zavolá DI bez problémov).

Záleží aj na DI frameworku, ktorý používaš. Je pomerne bežné, že ak máš v konštruktore parametre takých typov, ktoré sú v DI tiež registrované, tak kontajner ich tam je schopný dosadiť.
Napr. ak máš objekt ChciVytvorit s konštruktorom ChciVytvorit(I­MujService mujService), pričom pod IMujService si do kontajnera niečo zaregistroval, tak by to nemal byť problém. Opakujem ale, overiť, či to tvoj používaný framework podporuje. Viem, že defaultná DI v ASP.NET Core to podporuje určite.

Je však zle, ak máš napr. konštruktor ChciVytvorit(float hodnota). Alebo ak tam máš akýkoľvek iný typ, ktorý v DI registrovaný nie je, príp. sa do DI kontajneru ani registrovať nedá. V takomto prípade máš dve možnosti:

  • Položiť si otázku, či tá problematická hodnota naozaj musí byť získaná konštruktorom. Nedá sa z nej napr. spraviť parameter v metódach, ktoré ju potrebujú?
  • Na vytvorenie toho tvojho objektu môžeš využiť niečo na spôsob návrhového vzoru Factory. Niekedy sa to dá aj zaujímavo "skĺbiť"s DI, napr. v ASP.NET Core môžeš pri registrácii závislostí spraviť niečo ako services.AddTran­sient<IChciVyt­vorit>(s => new ChciVytvorit(42));

Ak ti tieto možnosti nevyhovujú, tak tú inicializáciu musíš dokončiť nejako dodatočne. Napr. cez nejakú metódu ChciVytvorit.Nac­ti(float hodnota), alebo cez public settery.

P.S.: Pre takéto rozširujúce otázky mimo pôvodnej témy založ radšej nové vlákno. Bude to potom ľahšie dohľadateľné pre iných ľudí s podobným problémom.

Editováno 24.11.2018 21:54
Nahoru Odpovědět 24.11.2018 21:52
if (this.motto == "") { throw new NotImplementedException(); }
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.