1

COM Interop VB 6.0テキストエディタをドラッグドロップしたアセンブリがあり、それを.NETラップコントロールとして使用しています...次に、Windowsフォームである新しいアセンブリで、アセンブリを上にドラッグドロップして使用を開始します。 、その変数を宣言し、それにイベントハンドラーを割り当てるので、たとえば、Assmbley abvoeがMyTextControlと名付けられている場合、このウィンドウフォームにはmytxtcntrlの変数とそのためのいくつかのイベントハンドラーがあります。

mytxtcntrl.TextEditor.ObjectDblClicked += new AxTextEditorLib._DTextEditorEvents_ObjectDblClickedEventHandler(ctlTEEditor_ObjectDblClicked);

だから今Sholud私はこれらのイベントハンドラーを「-=」で削除することさえ心配していますか?またはGCがそれを処理しますか?手動で行う必要がある場合、それを行う正しい場所はどこですか?それらをForm_Closedセクションに配置し、メモリプロファイラーを実行しましたが、効果はありませんでした。

4

2 に答える 2

3

イベントのサブスクライブを明示的に解除する必要があるのは、イベントソースオブジェクトがイベントサブスクライバーよりも長生きする場合のみです。そうしないと、サブスクライブするオブジェクトへの参照が保持され、ガベージコレクションが防止されます。

Winformsは、この種の事故を回避するためにかなり慎重に設計されました。通常、子コントロールによって発生するイベントをリッスンするために、フォームまたはユーザーコントロールでイベントハンドラーを記述します。これらの子コントロールの有効期間はフォームの有効期間と密接に関連しており、ユーザーがフォームを閉じると同時にすべてが破棄されます。ガベージコレクターはこれに悩まされることはなく、同時にそれらをすべて収集します。

ActiveXコントロールはこのパターンに適合します。これはフォームの子コントロールになるため、フォームが停止するのと同時に停止します。明示的なクリーンアップはまったく必要ありません。

説明されているようにこれが機能しないいくつかのコーナーケースがあります。古典的なものは、自分のコードで自分でコントロールを削除し、フォームを存続させる方法です。次に、イベントのサブスクライブを解除して、そのコントロールをガベージコレクションできるようにする必要があります。そして最も重要なことは、コントロールでDispose()を明示的に呼び出して、そのネイティブウィンドウが確実に破棄されるようにする必要があることです。そうしないと、ガベージコレクターでさえ解決できない永続的なリークが発生し、ウィンドウハンドルによってコントロールが有効に保たれます。

2番目のケースはSystemEventsクラスです。そのイベントは静的であり、クラスオブジェクトはプログラムが終了するまで存続します。アプリを終了せずに閉じることができる形式でイベントを使用する場合は、常にそのイベントの購読を明示的に解除する必要があります。

于 2012-12-11T16:53:49.537 に答える
2

いいえ、すべきではありません。GCがそれを処理します。オブジェクトを「取り除く」ことを心配する必要がある唯一の場所は、を実装するクラスを使用しているとき、IDisposableまたはで何かをしているときですSystem.Runtime.InteropServices

于 2012-12-11T16:29:13.550 に答える