3

アプリケーションに UI 要素があり、Panel を使用していくつかの潜在的なカスタム UserControls の 1 つをホストしています。パネル自体は、「ペイン」と呼んでいる非モーダル ダイアログのようなものを使用している標準化された UserControl でホストされています。

私が使用する方法は、標準ペインの新しいインスタンスをインスタンス化し、ロジックを使用して、その中にあるいくつかのオプションのホストされたコントロールの 1 つをPanel.Controls.Add(control). 次に、新しいペインをインターフェイス コントロールの設定された場所に追加します。ここでもControl.Controls.Add(control)、 が続きcontrol.BringToFront()、Z 位置を最大化するために が続きます。

これはすべてうまくいきますが、ペインを非表示にして破棄するときが来たら、それを完全に取り除くことはできないようです. もともと、私は単純Control.Controls.Remove(control)にペインの Parent プロパティを Nothing に設定して使用していました。これにより、ペインが消えるという望ましい効果が得られます。私の仮定は、コントロールが参照されなくなったため、GC がそれを破棄するというものでした。

しかし、私が見ているのは、次の外側のホスティング TabControl がタブ ページを変更したときに、コントロールがまだ画面に瞬時に表示され、まだどこかに存在していることを意味します。これはグラフィカルな問題ではなく、VS ウォッチ ウィンドウの [オブジェクト ID の作成] を使用してペイン オブジェクトが保持されていることを確認できます。(少なくとも、これは、コードからアクセスできる参照がなくても、オブジェクトとそのプロパティが引き続き存在することを直接確認できることを証明していると思います。)

交換してみた

Control.Controls.Remove(pane)
pane.Parent = Nothing

pane.Dispose()
GC.Collect()

私が確認できる Dispose 呼び出しは、親の Controls コレクションからコントロールを削除し、その Parent プロパティを Nothing に設定しますが、それ以上は行わないように見えます。GC を強制した後も持続し、画面上でときどきブリットします。

これはすべて、目的を果たした後にコントロールを削除して完全に破壊する適切な方法は何ですか?という最初の質問につながります。

4

1 に答える 1

0

MSDN のこの記事によると、オブジェクトがファイナライズ キューにあることによる副作用が発生しているようです。

Dispose メソッドは、破棄するオブジェクトの GC.SuppressFinalize メソッドを呼び出す必要があります。オブジェクトが現在ファイナライズ キューにある場合、GC.SuppressFinalize はその Finalize メソッドが呼び出されないようにします。

翻訳: finalize メソッドが呼び出されていないため、コントロールに関連付けられているリソースは解放されていません。もう少し掘り下げた後、私はあなたがすべきであることがわかりました

コンポーネントへの最後の参照を解放する前に、必ず Dispose を呼び出してください。そうしないと、使用しているリソースは、ガベージ コレクターが Component オブジェクトの Finalize メソッドを呼び出すまで解放されません。

この記事から。

したがって、最後の参照を解放するか、コンポーネントの finalize メソッドを直接呼び出して GC.Collect() が機能するようにする必要があります。

于 2013-06-20T16:42:19.720 に答える