Обнаружение утечек оконной ручки в приложении c # - PullRequest
2 голосов
/ 14 декабря 2009

Я столкнулся с этим исключением вчера:

Win32Exception: Fehler beim Erstellen des Fensterhandles

может перевести:

Win32Exception: Error while creating the windowhandle

Я знаю, как решить эту проблему (даже написал короткое сообщение в блоге по теме - на немецком языке)

Но я не знаю, где мое приложение могло «протекать», не располагая элементы управления, у которых все еще есть дескрипторы окон.

Есть ли способ обнаружить / найти случаи, которые

  • агрегат IDisposable
  • имеют Parent == null

Объекты, соответствующие этим ограничениям, кажутся хорошими кандидатами.

Ответы [ 3 ]

2 голосов
/ 14 декабря 2009

Любой приличный профилировщик памяти покажет вам контрольные экземпляры. Они не будут собирать мусор, их свойство Handle поддерживает их жизнь. Там будет около 10000 из них. Вы также можете увидеть это с помощью диспетчера задач, использовать View + Select Columns и отметить USER Objects. Наблюдение за увеличением количества во время тестирования приложения должно дать нам хороший совет.

Проверка кода тоже должна идти далеко, возможных способов утечки окна не так много. Сначала ищем наиболее распространенный случай, код, который вызывает Controls.Clear () или Controls.Remove / At (), но не содержит элемент управления. Следующим распространенным случаем является класс SystemEvents, вы должны явно отписаться от его событий. Остальные не так легко найти, вам нужен этот профилировщик.

Нахождение ручек во время выполнения технически возможно с помощью Reflection. Дескрипторы хранятся в System.Internal.HandleCollector.handleTypes []. Ну, технически.

0 голосов
/ 14 декабря 2009

Если они не собраны, это потому, что какой-то другой объект ссылается на ваши элементы управления, то ни вызова dispose, ни установки parent в null недостаточно. Возможно, вы привязываетесь к событиям, а не отрываетесь от них.

Специально проверьте случай присоединения к событиям от элементов управления, не содержащихся в атташе, в этом случае вы всегда должны отсоединяться от событий при утилизации элементов управления, если нет, элемент управления по-прежнему будет ссылаться на атташе и таким образом не выйдет

0 голосов
/ 14 декабря 2009

Каждый объект, который реализует IDisposable, имеет метод Dispose. Этот метод следует вызывать, когда объект больше не нужен. Используется ли он только в одном методе, окружите его оператором using (автоматически вызывает Dispose). Если это переменная-член вашего класса, ваш класс должен сам реализовать IDisposable. FxCop имеет правило проверки для этого.

...