Frage

Was haben Ressourcen manuell in aufgeräumt werden C # und was sind die Folgen nicht zu tun?

Zum Beispiel, sagen, dass ich den folgenden Code haben:

myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
// Use Brush

Wenn ich die Bürste mit der dispose-Methode nicht aufzuräumen, ich gehe davon aus der Garbage Collector gibt den Speicher bei Programmende verwendet? Ist das richtig?

Welche anderen Ressourcen muss ich manuell aufzuräumen?

War es hilfreich?

Lösung

Technisch alles, was von IDisposable erbt werden soll proaktiv angeordnet sind. Sie können die ‚Verwendung‘ Anweisung verwenden, um die Dinge einfacher zu machen.

http://msdn.microsoft.com/en-us/library /yh598w02.aspx

Manchmal werden Sie inkonsistente Verwendung von IDisposable abgeleiteten Objekte in der Dokumentation Beispielcode sowie Code sehen, die durch Tools (das heißt Visual Studio) erzeugt wird.

Was ist IDisposable schön ist, dass es Ihnen die Möglichkeit, proaktiv lassen Sie die darunter liegende nicht verwaltete Ressource gibt. Manchmal wollen Sie wirklich, dies zu tun - man denke Netzwerkverbindungen und Dateiressourcen zum Beispiel

.

Andere Tipps

Wenn Sie nicht über etwas verfügen, wird es gereinigt werden, wenn der Garbage Collector merkt, dass es keine weiteren Hinweise auf sie in Ihrem Code, die nach einiger Zeit sein kann. Für so etwas, ist es nicht wirklich wichtig, aber für eine offene Datei wird es wahrscheinlich.

Im Allgemeinen, wenn etwas eine Dispose-Methode hat, sollten Sie es nennen, wenn Sie mit ihm fertig sind, oder, wenn Sie können, wickeln Sie es in einer using Anweisung oben:

using (SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black))
{
    // use myBrush
}
  • Griffe auf interne Fenster Datenstrukturen.
  • Datenbank-Verbindungen.
  • Datei-Handles.
  • Netzwerkverbindungen.
  • COM / OLE-Referenzen.

Die Liste geht weiter.

Es ist wichtig, Dispose anrufen oder sogar noch besser, verwenden Sie das using Muster.

using (SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black))
{
    // use myBrush
}

Wenn Sie nicht über etwas verfügen, wird es gereinigt werden, wenn der Garbage Collector merkt, dass es keine weiteren Verweise darauf, die nach einiger Zeit sein kann.

Im Fall von System.Drawing.Brush, wird Windows hält interne Fenster Strukturen für den Pinsel in dem Speicher geladen, bis alle Programme geben ihren Griff.

Die Folgen der nicht Ihre IDisposables Entsorgung kann von einem vernachlässigbaren Leistungseinbußen variieren Ihre Anwendung abstürzt.

Das Brush-Objekt in Ihrem Beispiel wird von der GC gereinigt werden, wenn es, wie es sich anfühlt. Aber Ihr Programm hat nicht den Vorteil, dass wenig zusätzlichen Speicher hat man es gewonnen haben würde früher durch Reinigung. Wenn Sie eine Menge von Brush-Objekte verwenden könnte dies signifikant. Die GC ist auch effizienter bei Reinigung von Gegenständen, wenn sie nicht um sehr lange, weil es ein Generations Garbage Collector ist.

Auf der anderen Seite sind die Folgen nicht Datenbank Verbindungsobjekte Entsorgung könnte bedeuten, Sie aus gepoolten Datenbankverbindungen laufen sehr schnell und führen Ihre Anwendung zum Absturz bringen.

Verwenden Sie entweder

using (new DisposableThing...
{
    ...
}

Oder, wenn Sie benötigen für die Lebensdauer des in Ihrem Objekt zu einem IDisposable zu einem Bezug zu halten, implementieren IDisposable auf Ihrem Objekt und die Methode Dispose des IDisposable nennen.

class MyClass : IDisposable
{
    private IDisposable disposableThing;

    public void DoStuffThatRequiresHavingAReferenceToDisposableThing() { ... }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    //etc... (see IDisposable on msdn)

}

Im Allgemeinen alles, was IDisposable implementiert, sollten Sie bewirken, dass die Ressource, die Sie verwenden pausieren und zu erforschen.

GC geschieht nur dann, wenn Speicherdruck ist, so kann man nicht vorhersagen, wann. Obwohl ein Entladen der AppDomain wird es sicherlich auslösen.

Wie andere gesagt haben, verwenden ist dein Freund. Ich schrieb diesen Blog-Eintrag über wie IDisposable in einer ziemlich einfache Art und Weise zu implementieren, die durch Ausklammern der Teile weniger fehleranfällig ist, dass die am wichtigsten sind.

Ein Trick, den ich benutze, wenn ich kann mich nicht erinnern, ob ein bestimmtes Objekt eine Einweg-Ressource ist „.Dispose“ (höchstens!) Nach der Erklärung zu geben Intellisense zu bekommen für mich zu überprüfen:

MemoryStream ms = new MemoryStream().Dispose

Dann die .Dispose löschen und verwenden, um die Verwendung von () Richtlinie:

using(MemoryStream ms = new MemoryStream())
{
  ...
}

Nun, solange Sie die verwaltete Version der Ressourcen und rufen Sie nicht den Windows-APIs von selbst, sollten Sie in Ordnung sein. Nur Sorgen um eine Ressource zu löschen / vernichten, die wenn das, was Sie bekommen ein IntPtr ist, als „Fenster Griffe“ (und eine ganze Menge anderer Dinge) in .NET bekannt ist, und nicht ein Objekt.

Durch die Art und Weise, die Ressource (wie jedes andere .NET-Objekt) wird so schnell zur Sammlung gekennzeichnet werden, wie Sie den aktuellen Kontext verlassen, so dass, wenn Sie die Bürste in einer Methode erstellen, wird es markiert werden, wenn Sie es verlassen.

Wenn es (das heißt ein Teil des Rahmens) verwaltet wird Sie brauchen sich nicht um sie zu kümmern. Wenn es implementiert IDisposable nur wickeln Sie es in einem using Block.

Wenn Sie nicht verwalteten Ressourcen verwenden möchten, dann müssen Sie auf Finalisern lesen und Umsetzung IDisposable selbst.

Es gibt viel mehr Detail unter

Zuerst bei Beendigung des Programms, können Sie diesen Speicher für den Prozess im nehmen wird mit dem Prozess selbst beseitigt werden.

Bei der Verwendung entsorgt oder destructor in.net, muss man verstehen, dass die Zeit, wann die dispose-Funktion durch die GC genannt wird, ist nicht deterministisch. Deshalb empfiehlt es sich, die Verwendung oder den Aufruf der dispose explizit zu verwenden.

Wenn Ressourcen wie Dateien verwenden, Speicherobjekte wie Semaphoren und Ressourcen, die außerhalb der verwalteten Welt von .net leben müssen befreit werden.

Die SolidBrush zum Beispiel, müssen Sie entsorgen, weil es ein GDI-Objekt ist und das Leben außerhalb der .net Welt.

Der Garbage Collector nicht nur bei Programmende freizugeben, sonst wäre es nicht wirklich nützlich sein (auf jedem anständigen / letzten OS, wenn der Prozess beendet, alle seine Speicher ohnehin durch das Betriebssystem automatisch bereinigt wird).

Einer der großen Vorteile von C # im Vergleich zu C / C ++ ist, dass Sie sich zu befreien, zugeordneten Objekte nicht zu kümmern (die meiste Zeit zumindest); die gc tut es, wenn die Laufzeit (verschiedene Strategien wann / wie es zu tun) entscheidet.

Viele Ressourcen werden von der gc nicht gesorgt: Datei, in Bezug auf Threads Ressourcen (Schlösser), Netzwerkverbindungen, etc ...

Ein Ort, vorsichtig zu sein, sind Objekte, die aussieht klein GC sind aber nicht ... In dem Sharepoint-API zum Beispiel des SPWeb Objekt einen geringen Platzbedarf hat, so weit das GC betrifft und so wird mit niedriger Priorität für die Sammlung, aber es hat sich wirklich eine Menge Speicher (in dem Heap glaube ich) packte, dass die GC nicht kennt. Sie werden in einigen Spaß Speicherprobleme ausführen, wenn Sie eine ganze Reihe von ihnen sind zum Beispiel foreaching, immer daran denken, zu verwenden mit oder entsorgen!

Anstatt ein Objekt zu denken als Ressourcen „Halt“, die freigegeben werden müssen, ist es besser, in Bezug auf ein Objekt zu denken, wie veränderte etwas mit (möglicherweise außerhalb des Computers!), Die es überleben wird, könnte in einer Art und Weise sein, schädlich, wenn es nicht mehr rückgängig gemacht oder „gereinigt“, die aber nur das Objekt aufzuräumen. Während diese Änderung gewöhnlich die Form von einigen konkreten Gegenstand in einem Pool nimmt markiert ist „besetzt“, dessen genaue Form keine Rolle spielt. Was zählt, ist, dass die Änderungen rückgängig gemacht werden müssen, und das Objekt enthält Informationen, die das zu tun.

Der Garbage Collector werden alle verwalteten Ressourcen umgehen. In Ihrem Beispiel wird die Bürste gereinigt, wenn der Garbage Collector entscheidet, was einige Zeit passieren wird, nachdem der letzte Verweis auf die Bürste nicht mehr gültig ist.

Es gibt bestimmte Dinge, die manuell gereinigt werden müssen, aber die sind Zeiger von nicht verwalteten Quellen abgerufen, wie DLL ruft, nichts im .NET Framework benötigt diese Behandlung jedoch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top