Ho un'applicazione che sto creando che crea un gran numero di controlli di windows (pulsanti ed etichette, ecc.). Sono tutti fatti dinamicamente attraverso le funzioni. Il problema che sto avendo è che quando rimuovo i controlli e li dispongo, non vengono rimossi dalla memoria.Voglio indietro la mia memoria! Come posso disporre veramente di un controllo?
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;
}
Ora, per qualche ragione, questo proprio non mi sta dando la mia memoria indietro, in modo che quando il processo viene eseguito 5 volte, io alla fine con un out di violazione di memoria. Sono nuovo nell'oggettare e controllare lo smaltimento ma guardare ancora attraverso la vasta rete non mi ha ancora dato alcuna indicazione, quindi se qualcuno di voi ha un'idea, sarei grato di sentirlo.
AGGIORNAMENTO: Ho osservato la creazione e la distruzione degli oggetti utente (taskmanager) e ho notato che creo una scheda, aggiungo un gestore di clic, aggiungo un pannello, aggiungo 2 pulsanti sia con gestori di clic, tooltips e backimages (I pensa che questo è dove il problema è). L'app dice che crea 8 nuovi oggetti, ma quando eseguo il mio smaltimento, rimuovo solo 4 dalla memoria. Ho cercato di rimuovere i gestori di eventi, ma sembra non fare alcuna differenza.
RISOLTO !!! Mentre aggiungevo nuovi elementi al pannello, stavo passando loro un suggerimento (stupido, ma sto imparando). Per chiunque abbia lo stesso problema, (grazie ai commenti e alle indicazioni delle persone qui sotto. Ho scoperto per fare un controllo davvero dispose (come mi rendo conto di averlo inserito così scorrettamente) è:
1: SE AVETE un suggerimento, assicurarsi che sia accessibile NON fare quel che feci ad esempio:!!!
questo è sbagliato
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;
}
Se si esegue questa operazione, si perderà il puntatore al tooltip, e come il tooltip non è figlio dell'oggetto a cui è collegato (piuttosto, il tooltip fa un forte riferimento al controllo), quindi anche se distruggi il controllo, il tooltip che non puoi ccess mantiene vivo l'oggetto.
2: Prima di tutto, chiamare toolTip.RemoveAll(). Questo rimuove tutti i suoi legami ai controlli. Nota, se stavi usando questo suggerimento per altri controlli, hanno perso la punta dell'utensile.
3: Rimuovere tutti i controlli interni dalla control.ControlCollection base (. Se usano memoria non gestita, penso che sto facendo perche 'sta facendo il mio lavoro app così ...)
4: rimuovere eventuali gestori di eventi personalizzati.
5: infine, smaltire l'oggetto. Ho fatto una rapida funzione ricorsiva che lo fa abbastanza bene.
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();
}
Questo è estremamente grezzo e probabilmente c'è un modo molto migliore di farlo, ma a meno che qualcuno può venire con esso, questo avrà a che fare. Grazie per il tuo aiuto a tutti. Potresti aver salvato il mio intero progetto.
sono andato un ulteriore passo avanti, ho anche creato un metodo dispose ricorsivo per tutti gli oggetti e ancora ... Nessun ricordo indietro. private void RecursiveDispose (Control toDispose) { while (toDispose.Controls.Count> 0) RecursiveDispose (toDispose.Controls [0]); toDispose.Dispose(); } Questo, ancora una volta, rimuove visibilmente tutte le voci e cancella gli array di controllo, tuttavia non riesco ancora a recuperare memoria. –
Qualcos'altro sta causando l'errore di memoria insufficiente; in generale, non è mai necessario chiamare il garbage collector. Qual è il tuo codice attuale? –
Sì, ho appena notato un enorme accumulo di oggetti utente. Ma il mio codice rimuove solo alcuni di essi. Ad esempio, quando eseguo la creazione, crea 8 oggetti, ma quando dispongo gli oggetti, clearss 4 dalla memoria ... –