Frage

Ich habe eine Anwendung, die ich mache das schafft eine große Anzahl von Windows-Steuerelemente (Schaltflächen und Etiketten usw.). Sie sind alle Wesen dynamisch durch Funktionen gemacht. Das Problem, das ich habe, ist, wenn ich die Bedienelemente entfernen und entsorgen sie, werden sie nicht aus dem Speicher entfernt.

void loadALoadOfStuff()
{
    while(tabControlToClear.Controls.Count > 0)
        tabControlToClear.Controls[0].Dispose();
    //I even put in:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    foreach(String pagename in globalList)
        tabControlToClear.Controls.Add(MakeATab(pagename));
}

TabPage MakeATab(string tabText)
{
    TabPage newT = new MakeATab();
    newT.Text = tabText;
    //Fill page with controls with methods like this
    return newT;
}

Jetzt aus irgendeinem Grunde, dies einfach nicht gibt mir mein Gedächtnis zurück, so dass, wenn der Prozess 5 mal läuft, habe ich mit einem aus Speicherverletzung beenden. Ich bin neu in Objekt und Kontrolle zur Verfügung, aber das überwiegenden Netz noch hat mir nicht gegeben irgendwelche Anzeichen der Suche durch, so dass, wenn jemand von euch eine Idee hat, würde ich dankbar sein, es zu hören.

UPDATE: Ich habe den Benutzer beobachtet Objekte Schöpfung und Zerstörung (Taskmanager) und bemerkte ich eine Registerkarte erstellen, einen Click-Handler hinzuzufügen, fügen Sie ein Panel, fügen Sie 2 Tasten sowohl mit Click-Handler, Tooltips und backimages (ich glaube, das ist, wo das Problem ist). Die App sagt, es schafft 8 neue Objekte, aber wenn ich durch meine dispose laufen, entferne ich nur 4 aus dem Speicher. Ich habe versucht, die Event-Handler zu entfernen, aber es scheint keinen Unterschied zu machen.

GELÖST !!! Als ich neue Elemente in die Platte wurde hinzugefügt, wurde ich ihnen einen Tooltip (dumm, aber ich lerne) vorbei. . Für alle anderen, die das gleiche Problem hat, (dank Kommentare und Hinweise von Menschen, die unter I, um entdeckte eine Kontrolle wirklich dispose zu machen (wie ich weiß, ich so habe es falsch) lautet:

1: Wenn Sie ein TOOL TIP, sicherstellen, dass es zugänglich! Tun Sie das nicht, was ich tat! Z. B:

Das ist falsch!

TabPage MakeATab(string tabText)
{
    TabPage newT = new MakeATab();
    ToolTip myTip = new ToolTip();
    newT.Text = tabText;
    //Fill page with controls with methods like this
    myTip.SetToolTip(newT, "Something to say");
    return newT;
}

Wenn Sie dies tun, werden Sie den Zeiger auf den Tooltip verlieren, und wie der Tooltip ist kein Kind des Objekts es verbunden ist (besser gesagt, macht der Tooltip einen starken Bezug auf die Kontrolle), dann, selbst wenn Sie zerstören die Kontrolle, dass der Tooltip Sie können keinen Zugriff hält das Objekt am leben.

2: Vor allem, rufen toolTip.RemoveAll (). Dies entfernt alle die es Verbindungen zu den Kontrollen. Beachten Sie, wenn Sie diesen Tipp für andere Steuerelemente verwendet wurden, sie ihre Werkzeugspitze gerade verloren.

3: Entfernen Sie alle internen Kontrollen von der Basis Control.ControlCollection (., Wenn sie nicht verwalteten Speicher verwenden, ich denke, ich tue es dazu führen, es macht meine app Arbeit so ...)

. 4: Entfernen Sie alle benutzerdefinierten Ereignishandler

5: schließlich entsorgen Sie das Objekt. Ich machte eine schnelle recursing Funktion, die es ganz gut funktioniert.

    private void RecursiveDispose(Control toDispose)
    {
        while (toDispose.Controls.Count > 0)
            RecursiveDispose(toDispose.Controls[0]);

        if (toDispose.BackgroundImage != null)
            BackgroundImage = null;

        if (toDispose.GetType() == typeof(Button))
            toDispose.Click -= [Your Event];
        else if (toDispose.GetType() == typeof(TabPage))
            toDispose.DoubleClick -= [Your Event];
        else if (toDispose.GetType() == typeof(Label))
            toDispose.MouseMove -= [Your Event];

        toDispose.Dispose();
    }

Das ist sehr grob und es gibt wahrscheinlich eine viel bessere Möglichkeit, es zu tun, aber wenn jemand mit ihm kommen kann, wird dies zu tun. Danke für Ihre Hilfe jeder. Sie könnten nur mein gesamtes Projekt gespeichert haben.

War es hilfreich?

Lösung

Sie müssen auch den Verweis löschen.

while(tabControlToClear.Controls.Count > 0)
{ 
    var tabPage = tabControlToClear.Controls[0];
    tabControlToClear.Controls.RemoveAt(0);
    tabPage.Dispose(); 

    // Clear out events.

    foreach (EventHandler subscriber in tabPage.Click.GetInvocationList())
    {
        tabPage.Click -= subscriber;
    }
}

Andere Tipps

In diesem Code-Block Sie anrufen Entsorgen aber nicht den Verweis zu entfernen:

while(tabControlToClear.Controls.Count > 0)
    tabControlToClear.Controls[0].Dispose();

Sie müssen alle Verweise auf die Kontrolle (in der Controls-Auflistung zuzüglich registrierten Event-Handler sowie alle anderen Referenzen Sie haben könnten) entfernen für eine Steuerung für die Garbage Collection in Betracht.

void loadALoadOfStuff()
{
    while(tabControlToClear.Controls.Count > 0)
        tabControlToClear.Controls[0].Dispose();
    //I even put in:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    foreach(String pagename in globalList)
        tabControlToClear.Controls.Add(MakeATab(pagename));
}

Es scheint mir, Sie sind Neuzuteilung alle die Registerkarte Instanzen am Ende des Testverfahrens, so dass es klar ist, keinen Nutzen sie zunächst zu entsorgen. Überspringen Sie die letzten beiden Zeilen und sehen, ob das hilft.

Es gibt viele große Antworten auf die Frage gewesen war so weit, dass Erwähnung ein möglicher Grund werden die Objekte nicht freigegeben werden, sie sind alle Dinge wert.

Allerdings, wenn ich diese Art von Problem zu bekommen, verwende ich ein Speicher-Profiler auf die Referenz (en), um Hilfe Spur des > ANTS Memory Profiler RedGate ) einer der besten. (Sie haben einen 14-tägiges Schwanz, der mehr als lang genug ist, ein einziges Problem wie diese zu untersuchen.)

Dies ist einer der Gründe dafür, dass das schwache Ereignismuster verwendet wird, aber dass eine ganz neue Frage wäre .

(Die Lebensdauer von UI-Objekten, wenn Sie dynamisch Modifikator eine UI ist ein Minenfeld, gut für Taskmanager getan um zu überprüfen, dass Ihr Code funktioniert wie erwartet)

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