C# アプリケーションでウィンドウハンドルのリークを検出する
-
19-09-2019 - |
質問
昨日、この例外に遭遇しました。
Win32Exception: Fehler beim Erstellen des Fensterhandles
翻訳するかもしれません:
Win32Exception: Error while creating the windowhandle
私はこれを解決する方法を知っています(短い記事も書きました) ブログ投稿 このトピックについて - ドイツ語)
しかし、アプリケーションがまだウィンドウハンドルを持っている、破棄されていないコントロールをどこで「リーク」しているのかわかりません。
インスタンスを検出/見つける方法はありますか?
- 埋め込む
IDisposable
- 持っている
Parent == null
この制約に一致するオブジェクトが適切な候補と思われます。
解決
任意のまともなメモリプロファイラは、あなたのコントロールのインスタンスが表示されます。彼らは、Handleプロパティが生きそれらを保持し、ごみ収集されません。それらの万に近いがあります。また、タスクマネージャでそれを参照してくださいビュー+列の選択を使用して、ユーザーオブジェクトをチェックすることができます。アプリをテストしているとしてカウント増加を見てまともなヒントを提供する必要があります。
コードレビューがあまりにも長い道を行くべき、ウィンドウを漏洩する多くの方法がありません。最も一般的なケースについてまず見て、Controls.Clear()またはControls.Remove / AT()を呼び出すだけでなく、コントロールを配置しないコード。次の一般的なケースは、あなたが明示的にイベントを解除する必要があり、SystemEventsクラスです。残りはあなたがそのプロファイラが必要と思い、見つけるのはそれほど簡単ではありません。
、実行時にハンドルを自分で見つけることが反射して技術的に可能です。ハンドルはSystem.Internal.HandleCollector.handleTypes []に格納されています。まあ、技術的ます。
他のヒント
IDisposable
を実装するすべてのオブジェクトは、Dispose
の方法があります。オブジェクトが不要になったときに、このメソッドが呼び出されるべきではありません。それが唯一の方法で使用されている、using
文で、それを囲む(通話は自動的にDispose
)。それはあなたのクラスのメンバ変数である場合は、あなたのクラスがIDisposable
自体を実装する必要があります。 FxCopののは、このためのチェックルールを持っています。
であることは十分にあります。たぶん、あなたはイベントにアタッチし、それらからdettachingされていません。
コントロールを配置していないときにコントロールがまだアタッチによってので、参照され続ける場合は常に、イベントから切り離す必要があり、この場合には、アタッチに含まれていないコントロールからのイベントに取り付ける特殊ケースをチェックそれが解放されることはありません。