Muss ich beim Aufruf von Dispose() auf verwaltete Objekte?
Ich kann nicht glauben, ich bin immer noch verwirrt über diese aber, die Art und Weise, können schließlich Nagel es:
Ich habe eine Klasse, überschreibt OnPaint zu tun, einige Zeichnung. Um die Dinge zu beschleunigen, erstelle ich die Stifte, Pinsel etc. vor der hand, im Konstruktor, so dass OnPaint nicht brauchen, Sie zu erstellen und entsorgen Sie Sie.
Nun, ich sicherstellen, dass ich immer entsorgen Sie solche Objekte, aber ich habe das Gefühl, ich brauche das nicht, weil, trotz der Tatsache, dass Sie IDisposable implementieren, Sie sind die verwalteten Objekte.
Ist das richtig?
Danke für die vielen Antworten, das Problem hat sicherlich schon genagelt.
Ich bin froh, dass ich schon seit wachsam, immer mit 'mit', so dass ich nicht brauchen, um durch alle gehen, meinen code zu checken. Ich wollte nur klarstellen, dass ich nicht so eine sinnlose Benutzer.
Als ein beiseite, ich hatte eine seltsame situation, vor kurzem, wo ich die ersetzen musste, einen using-block verwenden und manuell aufrufen entsorgen! Ich werde ausgrabe und erstellen Sie eine neue Frage stellen.
- können Sie bitte die details (oder link) mit zu ersetzen 'verwenden' - block mit einem expliziten Aufruf von Dispose? Ich bin neugierig zu sehen, was dort passiert.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist es nicht richtig. Sie entsorgen müssen Objekte, die zur Umsetzung von
IDisposable
. Das ist, warum Sie implementierenIDisposable
- definieren Sie die Tatsache, dass Sie wickeln Sie (direkt oder indirekt) nicht verwaltete Ressourcen.In diesem Fall, die nicht verwaltete Ressource ist ein GDI-handle, und wenn Sie nicht zu entsorgen, wenn Sie tatsächlich mit Ihnen gemacht, Sie werden Leck, diese handles anzusprechen. Nun, diese insbesondere Objekte haben Finalizer, die bewirken, dass die Ressourcen freigegeben werden, wenn die GC kommt, aber Sie haben keine Möglichkeit zu wissen, Wann das geschehen wird. Es könnte sein, 10 Sekunden, könnte es sein, 10 Tage ab jetzt, wenn Ihre Anwendung nicht ausreichend Arbeitsspeicher, um die Ursache zu GC kick, und führen Sie den Finalizer auf diese Pinsel/Stifte/fonts/etc. Sie können am Ende verhungern die OS von GDI-Ressourcen vor dem GC-überhaupt merkt, was Los ist.
Darüber hinaus haben Sie keine Garantie, dass alle nicht verwalteten wrapper implementiert einen finalizer. Die .NET Framework selbst ist ziemlich konsistent in dem Sinne, dass Klassen implementieren
IDisposable
implementieren es mit den richtige Muster, aber es ist völlig möglich, für einige anderen - Klasse, um eine fehlerhafte Umsetzung, die nicht durch einen finalizer und daher nicht richtig Aufräumen, es sei dennDispose
genannt wird, ausdrücklich auf Sie. Im Allgemeinen, die Zwecke derIDisposable
ist, dass Sie eigentlich nicht wissen, oder kümmern uns um die spezifischen Implementierungsdetails; eher, wenn es Einweg, dann entsorgen Sie es, Punkt.Moral von der Geschichte: Immer entsorgen
IDisposable
Objekte. Wenn Ihre Klasse ist "Eigentümer" der Objekte, dieIDisposable
, dann sollte es umzusetzenIDisposable
selbst.Dispose
aufgerufen wird, werden aus dem gleichen thread, verursacht die Ressource initialisiert werden? Ich denke, der kann mehrere Situationen, in denen das nicht der Fall sein. Ehrlich gesagt, verwenden Sie nicht ThreadStatic für diese Art der Sache, halten kritische Ressourcen, die Sie verfolgen.Müssen Sie zu entsorgen.
Verwalteten Objekt zu verwalten, Ihre Speicher von selbst. Aber Speicher ist nicht die einzige Ressource, die ein Objekt verwendet.
Dispose()
soll zum release der anderen Ressourcen.Gibt es eine ausgeprägte Ironie in Ihrem Ansatz. Durch die vor-erstellen Sie die Stifte/Pinsel, Sie sind genau erstellen das problem, dass Dispose() versuchen zu lösen. Diese GDI-Objekte, um mehr, gerade so, wie Sie wäre, wenn Sie nicht, rufen Sie Dispose(). Es ist eigentlich noch schlimmer, Sie werden um zumindest bis das Formular geschlossen ist.
Sind Sie wahrscheinlich, um lange genug, um gefördert zu generation #2. Der garbage collector nicht einen gen - #2-Sammlung sehr oft, es ist jetzt mehr wichtig, rufen Sie Dispose() auf Sie. Dies tun, indem Sie die Dispose () - Methode des Formulars, aus dem Designer.cs-Datei zu Ihrem Formular.cs-Datei und fügen Sie die Dispose-Aufrufe.
Aber, das der Richtige Weg ist. Stifte und Pinsel sind sehr günstige Objekte. Erstellen Sie, wenn Sie Sie benötigen, in das Paint-Ereignis. Und verwenden Sie die using-Anweisung, so werden Sie sofort entsorgt. Verwenden Sie den Stopwatch-Klasse re-überzeugen Sie sich selbst dies nicht tatsächlich dazu führen, dass jede Verlangsamung.
Schrieb ich ein GDI+ - diagramming-Komponente, die verwendet viele Stifte und Pinsel. Habe ich Sie erschaffen, und entsorgen Sie Sie in den code-block, dabei war die Zeichnung und performance war nie ein Problem. Besser, dann mit einer lange gelebt handle, hanging around in der OS IMHO.
Haben Sie profilierten dies, um zu sehen, wenn Sie & Entsorgung dieser Objekte ist wirklich ein problem? Ich glaube nicht, dass es ist.
Sie machen Dinge viel einfacher für sich selbst und sicherlich weniger fehleranfällig, indem Sie einfach die folgenden erstellen-in-einem-mit-block-Muster.
Wenn Sie wollen, erstellen Sie noch einmal, dann auch implementieren IDisposable auf Ihre besitzenden Klasse und Durchlaufen der Verfügung über Ihr Eigentum Objekte. Keine Notwendigkeit für ein Destruktor (finalizer).
Gibt es fast keine Kosten auf diese Weise zu Objekten, die nicht wirklich brauchen, zu Entsorgen, aber es ist eine große Kosten, wenn Sie vergessen, Dispose für ein Objekt, die es brauchen.
Kein IDisposable für verwaltete Objekte, verwenden Sie nicht verwaltete Ressourcen.
Als eine Regel sollte man immer entsorgen, wenn Sie fertig sind.
Die Sie wirklich brauchen, um sich die Dokumentation für die Pinsel, Stifte etc.
Wenn Sie nicht mit unmanaged Ressourcen, die Sie kann nicht rufen Sie zu Entsorgen. Aber das mit/Dispose-Muster ist manchmal "missbraucht". Als Beispiel betrachten wir das ASP.NET MVC-framework. Hier können Sie etwas schreiben wie:
Wenn
Html.BeginForm(...)
aufgerufen wird, wird eineFORM
- tag wird ausgegeben. Wenn die using-Anweisung endet, dieDispose
aufgerufen wird, auf das Objekt zurückgegeben, die vonHtml.BeginForm(...)
. AufrufDispose
bewirkt, dass die EndeFORM
- tag gerendert werden. Auf diese Weise wird der compiler tatsächlich durchsetzen, die Paarung von FORM-tags, so dass Sie nicht vergessen, die schließende tag.Nein,
Pen
s undBrush
es sind nicht vollständig verwalteten Objekte.Enthalten Sie ein handle für eine nicht verwaltete Ressource, d.h. die entsprechenden GDI-Objekt in der zugrunde liegenden Grafik-system. (Nicht sicher über die genaue Terminologie hier...)
Wenn Sie nicht entsorgen Sie die handles nicht freigegeben werden, bis die Objekte sind fertiggestellt, die von der garbage-collector, und es gibt keine Garantie, dass es bald möglich sein wird, oder überhaupt.
Andere haben angedeutet, "mit" - Bausteine für die GDI-Objekte - hier ein code Beispiel:
Beachten Sie, dass Sie können so viele "mit" - Zeilen, wie Sie wollen für eine einzige code-block.
Ich denke, das ist eine schöne, saubere Umgang mit Disposable Objekten.
Nein, dass ist falsch. Ich Stimme mit Aaronaught.
Darüber hinaus empfiehlt Microsoft, in einem Mitte 2003 webcast an, Don Box vorgestellt, dass jeder .Net-Entwickler sollte entsorgen Sie Ihre eigenen Objekte, ob verwaltete oder nicht verwaltete, als dies verbessert die Performanz des Codes, indem Sie alles bis zu 20%. Wenn es richtig gemacht kann es eine erhebliche performance-Verbesserung. Es ist also eine Kernkompetenz, die jeder .net-Entwickler braucht, um zu wissen und zu verwenden.
Obwohl Sie gefragt, Stifte und Pinsel, Schrift ist eine Klasse mit paar seltsame Macken. Insbesondere, wenn man legt die schriftart für den Zweck der Einstellung eines Steuerelements Eigenschaft Schriftart aus, bleibt man verantwortlich für die Entsorgung der schriftart--Eigentum wird nicht übertragen, um die Kontrolle-aber diese Verantwortung kann durchgeführt werden, indem du die schriftart zu jeder Zeit-sogar sobald Sie die schriftart, die erstellt wird, bevor Sie es an die Steuerung. Es scheint Schriftart ist eine Kombination aus einem verwalteten Objekt Informationen und eine nicht verwaltete GDI-Ressourcen, und für einige Zwecke auch nur erstere benötigt wird. Komisch-design-Schrift sollte wurden zwei Klassen.
siehe meine Antwort hier auf einen ähnlichen thread. es sollte beantworten Ihre Fragen und erläutern Sie die Konsequenzen, wenn Sie nicht, rufen Sie Dispose auf.
Was passiert, wenn ich nicht rufen Sie Dispose auf dem Pen-Objekt