多数のウィンドウ コントロール (ボタンやラベルなど) を作成するアプリケーションを作成しています。それらはすべて関数を通じて動的に作成されています。私が抱えている問題は、コントロールを削除して破棄すると、それらがメモリから削除されないことです。
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;
}
なんらかの理由で、これでメモリが戻ってこないので、プロセスが 5 回実行されると、メモリ不足違反が発生します。私は処分に異議を唱えて管理するのは初めてですが、膨大なネットを調べてもまだ何の兆候もありません。
更新: ユーザー オブジェクトの作成と破棄 (タスク マネージャー) を見ていて、タブ ページを作成し、クリック ハンドラーを追加し、パネルを追加し、クリック ハンドラー、ツールチップ、およびバックイメージを備えた 2 つのボタンを追加していることに気付きました (ここにあると思います)。問題は)。アプリは 8 つの新しいアイテムを作成すると言っていますが、破棄を実行すると、メモリから 4 つしか削除されません。イベント ハンドラーを削除しようとしてきましたが、違いはないようです。
解決済み!!! パネルに新しいアイテムを追加するとき、ツールチップを渡していました (ばかげていますが、学習中です)。同じ問題を抱えている他の人のために、(以下の人々からのコメントと指示のおかげで。コントロールを本当に破棄するために発見しました(私が間違って言っていることに気付いたので))は次のとおりです。
1: ツールのヒントがある場合は、アクセス可能であることを確認してください。私がしたことをしないでください!例えば:
これは間違っています!
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;
}
これを行うと、ツールチップへのポインターが失われ、ツールチップは接続されているオブジェクトの子ではないため (むしろ、ツールチップはコントロールを強く参照します)、コントロールを破棄しても、アクセスできないツールチップは、オブジェクトを存続させます。
2: まず、toolTip.RemoveAll() を呼び出します。これにより、コントロールへの関連付けがすべて削除されます。このヒントを他のコントロールに使用していた場合は、ツール ヒントが失われていることに注意してください。
3: ベース コントロールから内部コントロールを削除します。
4: カスタム イベント ハンドラーをすべて削除します。
5: 最後に、オブジェクトを破棄します。私はそれを非常にうまく行う簡単な再帰関数を作りました。
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();
}
これは非常に大雑把で、おそらくもっと良い方法があるでしょう。助けてくれてありがとう。プロジェクト全体を保存しただけかもしれません。