JV Skrevet 30. oktober 2007 Del Skrevet 30. oktober 2007 (endret) Hei Har ett program som overvåker stadardskriver på PC-en og i visse tilfeller skal ny standardskriver settes. dette gjør jeg slik: public static bool setDefaultPrinter(string printerName) { try { System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.EnableRaisingEvents = false; proc.StartInfo.FileName = "rundll32.exe"; proc.StartInfo.Arguments = "printui.dll,PrintUIEntry /y /n \"" + printerName + "\""; proc.Start(); proc.Close(); return true; } catch (Exception ee) { return false; } } Det jeg ser i taskmanager er at hver gang denne kjøres ser det ut til at programmet bruker mer minne. Hvorfor? Er det noe jeg kan gjøre for å forhindre dette? Er ganske viktig at programmet ikke bruker for mye minne. Endret 30. oktober 2007 av JV Lenke til kommentar
Manfred Skrevet 30. oktober 2007 Del Skrevet 30. oktober 2007 (endret) proc.Dispose() Edit: Som DOKUMENTASJONEN så fint sier det: Releases all resources used by the Component Endret 30. oktober 2007 av Manfred Lenke til kommentar
JV Skrevet 31. oktober 2007 Forfatter Del Skrevet 31. oktober 2007 Takk takk. Får prøve den. Forstår at "alt" står i DOKUMENTASJONEN men ikke alle har tid til å lese hele DOKUMENTASJONEN da jeg vil tro denne er rather stor. Bruker den når jeg vet hva jeg skal se etter, men hadde jeg visst om .Dispose() ville jeg sikkert også kunne lese om den. Lenke til kommentar
Manfred Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 iom at Dispose() er ganske "vanlig" i .net, da mange klasser arver av IDisposeable, så bør dette være noe som .net-utviklere vet om. Lenke til kommentar
j000rn Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 Bruk using isteden: using(System.Diagnostics.Process proc = new System.Diagnostics.Process()) { proc.EnableRaisingEvents = false; proc.StartInfo.FileName = "rundll32.exe"; proc.StartInfo.Arguments = "printui.dll,PrintUIEntry /y /n \"" + printerName + "\""; proc.Start(); proc.Close(); } Da blir proc GARANTERT disposet uten at du strenger .dispose, try/catch og if-setninger, etc... Btw: .Net gir ikke nødvendigvis fra seg minnet med en gang. Jeg tror ikke du har en minnelekasje, men rett og slett at garbage collectoren ikke har frigitt minnet ennå. Hvis dette er et problem for deg kan du prøve å kjøre GC.Collect(); Lenke til kommentar
Manfred Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 Tror strengt tatt også at det ikke er så lett å lage minnelekkasje i .net, nei Faktisk ikke så dum vane å venne seg til å bruke using. Bruker det i mange sammenhenger selv. Litt enklere å holde styr på om objektet finnes, eller om du har disposet det, osv.. når det ligger i et scope Lenke til kommentar
j000rn Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 Tommelfingelregel: ALLE klasser som implementerer IDisposable SKAL det brukes 'using' på. Regelen bør kun brytes i noen få tilfeller der det er nødvendig og der man VET hva man driver med... Lenke til kommentar
Manfred Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 ...spør du GeirGrusom er det de tøffe som passer på å dispose selv Lenke til kommentar
j000rn Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 (endret) ...spør du GeirGrusom er det de tøffe som passer på å dispose selv Ja, men DU er jo ikke tøff Endret 31. oktober 2007 av jorn79 Lenke til kommentar
JV Skrevet 31. oktober 2007 Forfatter Del Skrevet 31. oktober 2007 Ok. Takker. Skal titte litt på using jeg. Lenke til kommentar
Manfred Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 Forstår at "alt" står i DOKUMENTASJONEN men ikke alle har tid til å lese hele DOKUMENTASJONEN da jeg vil tro denne er rather stor. Bruker den når jeg vet hva jeg skal se etter, men hadde jeg visst om .Dispose() ville jeg sikkert også kunne lese om den. Jeg har heller ikke sagt at du skal lese hele, men kanskje de delene som omhandler det objektet du har spørsmål om? Siden du også "vil tro" at dokumentasjonen er ganske stor, så har du tydeligvis ikke prøvd en gang. Lenke til kommentar
GeirGrusom Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 De sterke disposer manuelt. Etter det jeg har forstått, så gjør disposing noe slikt: (obj as IDisposing).Dispose(); Så det spiller ingen rolle, men med using er det enklere å huske. Lenke til kommentar
j000rn Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 (endret) De sterke disposer manuelt. Etter det jeg har forstått, så gjør disposing noe slikt: (obj as IDisposing).Dispose(); Så det spiller ingen rolle, men med using er det enklere å huske. Ja, men using() sørger også for at man slipper try/finally, if (for å sjekke om objekter er null ), etc... Den blir automatisk disposet når objektet går ut av scope.... EnDisposableKlasse obj; try { obj = new EnDisposableKlasse(); obj.Noe(); // kræsjer? } catch { throw; } finally { if( obj != null ) obj.Dispose(); } vs. using(EnDisposableKlasse obj = new EnDisposableKlasse()) { obj.Noe(); } Forskjellen er 4 linjer kode istendefor 15 Endret 31. oktober 2007 av jorn79 Lenke til kommentar
Spartakus Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 using(EnDisposableKlasse obj = new EnDisposableKlasse()) { obj.Noe(); } Og hva med feilhåndtering hvis obj.Noe() kaster en exception? Lenke til kommentar
j000rn Skrevet 31. oktober 2007 Del Skrevet 31. oktober 2007 (endret) using(EnDisposableKlasse obj = new EnDisposableKlasse()) { obj.Noe(); } Og hva med feilhåndtering hvis obj.Noe() kaster en exception? Det er hele poenget! Da forsvinner den ut av using() scope't, og blir automagisk disposet! Funksjonaliteten i de to kodesnuttene er helt lik. Og som du ser så er det mye enklere å lage kode som oppfører seg *riktig* vha using(). Endret 31. oktober 2007 av jorn79 Lenke til kommentar
GeirGrusom Skrevet 1. november 2007 Del Skrevet 1. november 2007 Using er genialt, og en av grunnene er at objektet faller ut av scope. Lenke til kommentar
HDSoftware Skrevet 1. november 2007 Del Skrevet 1. november 2007 Bare for å ha ting på det rene. Om en objekt ikke implementerer iDisposable, vil da fortsatt USING sørge for å dispose objektet riktig? Eller bruker Usin iDisoable interfacet implisit? Eks. Hva skjer her? class EnKlasse { int enInt; } using(EnKlasse k = new EnKlasse()) { k.enInt = 10; } Vil k være disposet skikkelig nå? Eller må jeg implementere iDisposable for at dette faktisk skal virke? En annen ting. Hva med objekter som er definert i en klasse utefor metoder? Man kan vel ikke bruke USING utenfor CODE scope? Altså, hvordan ville man skrevet denne klassen med USING bruk? class MinKlasse { EnAnnenKlasse k = new EnAnnenKlasse(); public void SettIVerdi() { k.i = 10; } public void VisIVerdi() { Console.WriteLine(k.i.ToString()); } } class EnAnnenKlasse { int i; } antagligvis er 90% av min kode laget på denne måten. Hvordan skal jeg da kunne bruke USING? Lenke til kommentar
steingrim Skrevet 1. november 2007 Del Skrevet 1. november 2007 using(EnDisposableKlasse obj = new EnDisposableKlasse()) { obj.Noe(); } Og hva med feilhåndtering hvis obj.Noe() kaster en exception? Det er jo nettopp det at obj.Noe() kan kaste en exception som er grunnen til at man bruker using Som nevnt tidligere i tråden, using er bare en finere måte å si try-finally plusspluss. Lenke til kommentar
Manfred Skrevet 1. november 2007 Del Skrevet 1. november 2007 Og poenget med å gjenta svaret var...? Prøve å vise at du også kan noe? Lenke til kommentar
j000rn Skrevet 1. november 2007 Del Skrevet 1. november 2007 (endret) Bare for å ha ting på det rene. Om en objekt ikke implementerer iDisposable, vil da fortsatt USING sørge for å dispose objektet riktig? Eller bruker Usin iDisoable interfacet implisit? Eks. Hva skjer her? class EnKlasse { int enInt; } using(EnKlasse k = new EnKlasse()) { k.enInt = 10; } Vil k være disposet skikkelig nå? Eller må jeg implementere iDisposable for at dette faktisk skal virke? En annen ting. Hva med objekter som er definert i en klasse utefor metoder? Man kan vel ikke bruke USING utenfor CODE scope? Altså, hvordan ville man skrevet denne klassen med USING bruk? class MinKlasse { EnAnnenKlasse k = new EnAnnenKlasse(); public void SettIVerdi() { k.i = 10; } public void VisIVerdi() { Console.WriteLine(k.i.ToString()); } } class EnAnnenKlasse { int i; } antagligvis er 90% av min kode laget på denne måten. Hvordan skal jeg da kunne bruke USING? Du kan ikke bruke using() på klasser som ikke implementerer IDisposable. Hvis du bruker klasser som kan "lekke ressurser" på den måten du har vist, så bør DIN klasse implementere IDisposable, og være nøye på å .Dispose() objektene du har laget i din sin klasse din .Dispose(). Og når du bruker klassen din bør du bruke using på den. I eksempelet ditt bruker du kun int klassen, og i dette tilfellet er det ikke nødvendig å tenke på dette. class MinKlasse : IDisposable { // .. kode her... public void Dispose() { // Sjekke at EnAnnenKlasse != null, og dispose, etc... } } "Lekke ressurser" betyr: Siden objektene du bruker sansynligvis implementerer IDisposable så vil ressursene kun lekke til GC kjører. Men for endel ressurser som IO(filer), databaseconnections, GDI, etc så bør disse frigis så fort som mulig. ---- Eksmpel: Jeg har laget en egen Query klasse som tar for seg databasespørringer. Når denne klassen blir brukt vil connection og datareader objekter være åpne mens klassen "kjører". Derfor har jeg latt denne klasssen implementere IDisposable, og i .Dispose() passer jeg på å lukke alle connection og datareader objekter som har blitt laget. Dette fordi jeg ikke kan bruke using() på connection og datareader objektene som blir værende åpne "lengre enn 1 funksjon"... using( Query q = new Query() ) { q.AddParameter("@Test", 5); q.Execute("spTest"); while( q.Read() ) Console.WriteLine( q["Test"] ); } Endret 1. november 2007 av jorn79 Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå