Проблема графики в .NET с GroupBoxes и NumericUpDowns - PullRequest
0 голосов
/ 08 сентября 2011

У нас возникла проблема с графикой, которая, похоже, связана со средой выполнения .NET.Время от времени границы всех групповых блоков и стрелок всех числовых значений в нашем приложении исчезают.Похоже, что по какой-то причине они перестают перекрашиваться, потому что в NumericUpDowns иногда есть графический мусор, где должны быть стрелки.

Мы подозреваем, что ошибка возникает после перезапуска приложения несколько раз.Как только проблема возникает, перезапуск приложения не помогает.Но закрытие всех процессов .NET и перезапуск приложения делают проблему исчезающей, это указывает на проблему во время выполнения .NET.

Наше приложение представляет собой приложение WinForms, разработанное с использованием VS 2008 SP1 и предназначенное для .NET 3.5.Он работает в Windows XP с пакетом обновления 3 (SP3) в классическом режиме (политика компании-клиента).

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

РЕДАКТИРОВАТЬ: Как я могу сознательно исчерпать кучу рабочего стола, чтобы воспроизвести проблему?Я играл с диспетчером задач и GdiUsage, создавая ручки, кисти и шрифты, как сумасшедшие.Конечно, не вызов утилизировать, но и хранить их в списке, чтобы избежать сбора мусора.Тем не менее, после создания 100 000 перьев со случайными цветами у меня есть только несколько объектов в соответствии с инструментами монитора.

List<Pen> pens = new List<Pen>();
Random rnd = new Random();
for(int i = 0; i < 100000; i++)
  pens.Add(new Pen(Color.FromArgb(rnd.Next())));

1 Ответ

2 голосов
/ 12 сентября 2011

Это контрольный признак программы, у которой есть утечка дескрипторов.Windows поддерживает кучу объектов GDI и User для всех программ, запущенных на компьютере.Существует квота в 10 000 дескрипторов для каждого отдельного процесса, но пара утечек или тяжелых программ может заполнить кучу до отказа.Как только это произойдет, запросы на ручку для рисования границы (например) не будут выполнены, и материал перестанет рисоваться.Это не всегда проверяется, особенно в собственном коде.

Вы можете диагностировать его с помощью Taskmgr.exe, вкладка Процессы.Используйте View + Select Columns и отметьте Handles, USER Objects и GDI Objects.Следите за программой, в которой их много (сотни) и число которых постоянно увеличивается во время использования программы.

Вы можете пропускать дескрипторы в программе .NET, если не используете Dispose () или с использованием оператора для одноразовых объектов, таких как ручки, кисти, шрифты, растровые изображения.И когда эта программа иначе не использует достаточно памяти для запуска сборки мусора, чтобы финализатор мог освободить дескриптор.

...