Dispose()
-
Guten Tag Euch,
bei .NET gibt es ja kein Gegenstück zum new Operator, nämlich delete. Manche
Klassen verfügen über die Methode Dispose(), wenn sie IDisposable implement-
ieren. Wann macht das Sinn, wenn doch die Garbage-Collection alles aufräumt ?
-
Antworten auf solche trivialen Fragen findet man bei google
-
Oh oh, ich sehe bei dir gefähriches Halbwissen. Der GarbageCollector räumt mit nichten alles hinter dir auf.
Sobald du z.B. auf Unmanaged-Ressourcen zugreifst musst du sicherstellen, dass diese auch aufgeräumt werden.
Bestes Beispiel wäre hier die Verwendung von Streams. - Wenn du zyklisch immer wieder Streams erstellst ohne Dispose zu verwenden, wird dir deine Anwendung wegbrechen da nicht mehr genug Speicher vorhanden ist.
Folgendes würde nach geraumer Zeit zu einer Exception führen:
private void WriteFile(byte[] data) { FileStream fs = new FileStream("mycsv.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite); fs.Write(myBytes, 0, myBytes.Length); fs.Flush(); }
-
C#Coder schrieb:
Wann macht das Sinn, wenn doch die Garbage-Collection alles aufräumt ?
Der GC läuft irgendwann mal. Vielleicht auch nie.
Die meisten Resourcen sollten aber sofort, oder zumindest deterministisch freigegeben werden. Also implementiert und verwendet man
IDisposable
.
Oder auch nicht, dann schreibt man halt das nächste schlechte .NET Programm.
-
inflames2k schrieb:
Folgendes würde nach geraumer Zeit zu einer Exception führen:
private void WriteFile(byte[] data) { FileStream fs = new FileStream("mycsv.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite); fs.Write(myBytes, 0, myBytes.Length); fs.Flush(); }
"Nicht genug Speicher" ist meistens nicht das schlimmste Problem.
Der Code oben sollte eigentlich schon beim 2. Aufruf fetzen. Sharing violation.
-
Ja sicher, bin ja nicht auf die explizite Exception eingegangen.
Der Vollständigkeithalber noch wie man es richtig machen sollte:
private void WriteFile(byte[] data) { using(FileStream fs = new FileStream("mycsv.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { fs.Write(myBytes, 0, myBytes.Length); fs.Flush(); } }
Bei dem Flush bin ich mir nicht mehr ganz sicher, ob's optional war wenn dispose implizit aufgerufen wird. - Ich lass es mal drin. - Schadet ja nicht.
-
Statt der using Anweisung, könnte man unten auch fs.Close(); verwenden ?
-
Ja gut beim Stream funktioniert das aufgrund der Implementierung von Close, da dieses intern Dispose aufruft. Dann stelle dir einfach vor, du ladst Bilder in deinem Programm. - Diese musst du ebenfalls explizit wieder freigeben und diese haben keine Close-Methode.
-
Ok, Danke für Euch !
-
inflames2k schrieb:
Ja sicher, bin ja nicht auf die explizite Exception eingegangen.
Achso. Auf Grund vom Satz davor dachte ich du meinst ne OutOfSonstwasException
inflames2k schrieb:
Bei dem Flush bin ich mir nicht mehr ganz sicher, ob's optional war wenn dispose implizit aufgerufen wird. - Ich lass es mal drin. - Schadet ja nicht.
Sollte egal sein.
Mit explizitem .Flush() gibt's halt nen anderen (u.U. aussagekräftigeren) Stacktrace wenn dabei 'was schief geht.
-
Ist es nicht so, dass wenn zu wenig zusammenhängender Speicher vorhanden ist,
die Garbage-Collection aufgerufen wird, und unerreichbarer Speicher freigegeben
wird ? Wenn ich in eine Bitmap-Variable bm, eine Bitmap1 lade und später eine
Bitmap2, dann ist die Bitmap1 unereichbar, und müsste von der Garbage-Collection
entfernt werden. Ist dieser Fall langsamer als bm.Dispose() ?
-
Der Garbage Collector wird einen Scheiß tun. Der gibt das Bild nicht frei wenn du nicht zuvor Dispose aufgerufen hast, hintergrund ist der, dass bis der GC irgendwann mal die Finalizer für die Bilder aufruft ist dein Speicher längst voll.
"Always call Dispose before you release your last reference to the Image. Otherwise, the resources it is using will not be freed until the garbage collector calls the Image object's Finalize method."
MSDN schrieb:
Rufen Sie Dispose auf, wenn Image nicht mehr benötigt wird. Die Dispose-Methode bewirkt, dass Image nicht mehr verwendet werden kann. Nach dem Aufruf von Dispose müssen Sie alle Verweise auf Image freigeben, sodass der von Image belegte Speicher bei der Garbage Collection wieder zugänglich gemacht werden kann.
Rufen Sie immer Dispose auf, bevor Sie den letzten Verweis auf Image freigeben. Andernfalls bleiben die verwendeten Ressourcen reserviert, bis die Garbage Collection die Finalize-Methode des Image-Objekts aufruft.
-
Ok, das habe ich nicht gewusst, Sorry
-
MSDN: "Rufen Sie immer Dispose auf, bevor Sie den letzten Verweis auf
Image freigeben." Dumme Frage: was heisst hier freigeben ?
-
Freigeben eines Verweises heißt hier das du den Member / die Variable auf Null setzt. - Je nach Scope ist das wichtig, da der GC nicths aufräumt wo Verweise drauf liegen.