Проблема с Winforms - Ошибка при создании дескриптора окна

Мы наблюдаем эту ошибку в приложении Winform. Может ли кто-нибудь помочь в том, почему вы видите эту ошибку, и, что более важно, как ее исправить или избежать.

System.ComponentModel.Win32Exception: Error creating window handle.
   at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.OnVisibleChanged(EventArgs e)
   at System.Windows.Forms.ButtonBase.OnVisibleChanged(EventArgs e)
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
67
0
109 867
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

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

Ответ принят как подходящий

Вы запускали Process Explorer или диспетчер задач Windows, чтобы просматривать объекты GDI, дескрипторы, потоки и объекты USER? Если нет, выберите эти столбцы для просмотра (в диспетчере задач выберите «Просмотр» -> «Выбрать столбцы» ... Затем запустите приложение, посмотрите на эти столбцы для этого приложения и посмотрите, действительно ли один из них становится большим.

Возможно, у вас есть компоненты пользовательского интерфейса, которые вы очистили считать, но не были удалены.

Вот ссылка об этом может быть полезно.

Удачи!

Я столкнулся с этой проблемой и обнаружил, что мое приложение сообщило о 9600+ объектах USER и 1800+ объектах GDI. Моя проблема в том, что я не делаю ничего плохого, я просто добавляю много элементов в FlowLayoutPanel. Я думаю, мне придется "пролистать" отображаемые данные ...

Gerardo Contijoch 14.05.2015 21:24

Предложение о нехватке памяти не похоже на плохую зацепку.

Что делает ваша программа, чтобы получить эту ошибку?

Создает много окон или элементов управления? Создает ли он их программно, а не во время разработки? Если да, то делаете ли вы это в цикле? Этот цикл бесконечен? Вы потребляете ошеломляющие количества памяти каким-то другим способом?

Что происходит, когда вы смотрите, какая память используется вашим приложением в диспетчере задач? Он взлетает до Луны? Или еще лучше, как было предложено выше, используйте монитор процесса, чтобы погрузиться в детали.

Предел дескрипторов Windows для вашего приложения составляет 10 000 дескрипторов. Вы получаете сообщение об ошибке, потому что ваша программа создает слишком много дескрипторов. Вам нужно будет найти утечку памяти. Как предлагали другие пользователи, используйте профилировщик памяти. Я также использую .Net Memory Profiler. Кроме того, убедитесь, что вы вызываете метод dispose для элементов управления, если вы удаляете их из формы до, форма закрывается (в противном случае элементы управления не будут удалены). Вам также необходимо убедиться, что в элементе управления не зарегистрировано никаких событий. У меня такая же проблема, и, несмотря на то, что я уже знаю, у меня все еще есть утечки памяти, которые продолжают ускользать от меня ...

См. этот мой пост об "Ошибка создания дескриптора окна" и его отношение к объектам USER и куче рабочего стола. Предлагаю несколько решений.

У меня такая же ошибка в моем приложении. Я загружаю много элементов управления на одной странице. В событии нажатия кнопки я очищаю элементы управления. Очистка элементов управления не освобождает элементы управления из памяти. Поэтому удалите элементы управления из памяти. Я просто прокомментировал метод controls.clear () и добавил несколько строк кода для удаления элементов управления. Что-то вроде этого

для каждого ctl в качестве элемента управления в коллекции controlcollection

ctl.dispose ()

Следующий

Эта проблема почти всегда связана с количеством объектов GDI, пользовательских объектов или обработчиков и обычно нет из-за нехватки памяти на вашем компьютере.

Когда я отслеживаю одну из этих ошибок, я открываю ProcessExplorer и смотрю эти столбцы: дескрипторы, потоки, объекты GDI, объекты USER, частные байты, виртуальный размер и рабочий набор.

(По моему опыту, проблема обычно заключается в утечке объекта из-за того, что обработчик событий удерживает объект и препятствует его удалению.)

Да .. Как решить эту проблему?

Munavvar 10.06.2019 13:13

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

AlfredBr 14.06.2019 17:04

Что ж, в моем случае именно объекты USER вышли из-под контроля. Я заглянул в диспетчер задач Windows и, конечно же, количество объектов USER было ровно 10'000.

Я динамически встраиваю листы свойств и списков в страницы вкладок, устанавливая для свойства Parent свойства или панели контейнера листа списка значение страницы вкладок. Я условно рециркулирую или повторно создаю формы листа свойств и списка в зависимости от типа перечисляемой коллекции или типа класса проверяемого объекта.

NB: В Delphi у всех элементов управления были свойства Owner и Parent. Даже если изменить свойство Parent элемента управления, он все равно будет удален его владельцем, когда элемент управления-владелец будет уничтожен.

В C# кажется, что если элемент управления, например, Панель программно переназначается, скажем, из формы на страницу вкладки путем изменения свойства Panel.Parent, вызов Dispose () в форме не удаляет панель, как и вызов Controls.Clear () на странице вкладок. Даже прямой вызов Panel.Dispose () на самом деле не удалит его, если для его Parent заранее вручную не установлено значение null.

Определенно слишком много дескрипторов (проблема с утечкой памяти):

IT-джунгли: System.ComponentModel.Win32Exception: ошибка при создании дескриптора окна

Я добавил проверку, которая заставляет работать ...

if (_form.Handle.ToInt32() > 0)
{
   _form.Invoke(method, args);
}

это всегда верно, но без этого форма выдает ошибку. Кстати, моя ручка составляет около 4,9 миллиона

Обратите внимание, что реализация свойства Handle проверяет, создан ли дескриптор, а если нет, создает его. Заглянем в исходный код .NET: public IntPtr Handle { get { ...if (!this.IsHandleCreated) { this.CreateHandle(); } ...}} Свойство IsHandleCreated вернет вам истину / ложь без создания дескриптора.

Paul Williams 16.08.2013 18:03

Другие вопросы по теме