- Remove From My Forums
Ошибка при создании дескриптора окна.
-
Вопрос
-
Доброго времени суток!
Вопрос к понимающим…
VB 2010 Express: Есть процедура, которая производит заполнение панели (Panel) пользовательскими элементами управления (Control) — т.е. создает некий интерфейс. Процедура вызывается по запросу пользователя. При большом
количестве добавляемых Contol возникает Win32Exeption: «Ошибка при создании дескриптора окна». Явно отследить, в каком месте кода возникает исключение, или невозможно («Нет доступных исходных файлов») или VB
«привязывает» исключение к разным местам кода. У меня есть такое подозрение, что «где-то что-то переполняется», т.к. при вызове процедуры с постоянным кол-вом добавляемых Control, исключение возникает
при определенном числе раз вызова процедуры. Тоже самое происходит в скомпилированном EXE-файле. Буду очень признателен, если кто-нибудь подскажет чем это может быть вызвано. Спасибо.
Ответы
-
Хм. А перед добавлением новых Control, вызов метода Controls.Clear для Panel (в которую добавляются Control) — это неправильно? т.е. Panel надо чистить циклом Control.Dispose?
Метод Clear просто очищает коллекцию Controls. Сами контролы продолжают висеть в памяти до очередной сборки мусора.
Может подскажите, а если добавляемая Panel, не будет содержать Control, а в Panel необходимые элементы рисовать через GreateGraphics — это улучшит ситуацию?
Может улучшить, может ухудшить. Смотря как рисовать будете. Вот полезная ссылка:
Преодолевая границы Windows: объекты USER и GDI (часть 2). Общее количество дескрипторов не должно превышать 10000, а в их число входят и кисти, и перья, так что рисуя вручную тоже можно насоздавать (и не удалить) кучу дескрипторов.
Попробовал чистить родительскую Panel циклом — разницы не заметил. Может надо ка-то по-хитрому?
Нужно диспозить все контролы в коллеции panel.Controls, а также рекурсивно в коллекциях самих этих контролов. В частности, если используются UserControl, то у них.
-
Предложено в качестве ответа
19 августа 2014 г. 7:03
-
Помечено в качестве ответа
Dmitriy VereshchakMicrosoft contingent staff, Moderator
19 августа 2014 г. 7:03 -
Снята пометка об ответе
Dmitriy VereshchakMicrosoft contingent staff, Moderator
19 августа 2014 г. 7:05 -
Помечено в качестве ответа
Dmitriy VereshchakMicrosoft contingent staff, Moderator
20 августа 2014 г. 13:23
-
Предложено в качестве ответа
6 / 6 / 3
Регистрация: 01.04.2015
Сообщений: 20
1
03.06.2015, 16:42. Показов 3476. Ответов 2
Программа выдает ошибку в строке 39
Необработанное исключение типа «System.ComponentModel.Win32Exception» в System.Windows.Forms.dll
Дополнительные сведения: Ошибка при создании дескриптора окна.
могу предположить, что это из-за того, что в форме 3 используется тот же код с теми же переменными, только другими цифрами, если это так, то что делать?
| C# | ||
|
Добавлено через 1 час 14 минут
![]()
Сообщение от Nyusch

в форме 3 используется тот же код с теми же переменными, только другими цифрами, если это так, то что делать?
это не так, я поменяла называния btn и ошибка осталась 
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Что ж, в моем случае это определенно были объекты ПОЛЬЗОВАТЕЛЯ, которые вышли из-под контроля. Я заглянул в Диспетчер задач Windows и, конечно же, количество объектов ПОЛЬЗОВАТЕЛЯ было ровно 10 000.
Я динамически встраиваю листы свойств и списков в страницы вкладок, устанавливая свойство Parent панели контейнера свойства или листа списка на страницу вкладок. Я условно перерабатываю или воссоздаю формы листа свойств и списка в зависимости от типа перечисляемой коллекции или типа класса проверяемого объекта.
NB: в Delphi все элементы управления имели свойства Owner и Parent. Даже если изменить свойство Parent элемента управления, оно все равно будет удалено его владельцем, когда владеющий им элемент управления будет уничтожен.
В C# кажется, что если элемент управления, например панель, программно переназначается, скажем, из формы на страницу вкладок путем изменения свойства Panel.Parent, вызов Dispose() в форме не приведет ни к удалению панели, ни к вызову элементов управления. .Clear() на странице вкладок. Даже прямой вызов Panel.Dispose() на самом деле не удалит его, если только его Parent вручную не установлен в null заранее.
Есть winform форма, из базы данных подгружается список определенных данных, на базе которых формируется что-то типа репитера на базе ControlCollection. Элемент репитера — кастомный контрол, на котором есть около 5-6 стандартных контролов (групировка, лейблы, текстбоксы, кнопки). Каждый элемент списка — соответствует такому кастомному контролу. При попытке вставить более чем определенное количество элементов (в моем случае около 900) возникает «Ошибка при создании дескриптора окна». При том, что форма при инициализации на какое то время зависает.
Exception Information
*********************************************
Exception Type: System.ComponentModel.Win32Exception
NativeErrorCode: 8
ErrorCode: -2147467259
Message: Ошибка при создании дескриптора окна.
Data: System.Collections.ListDictionaryInternal
TargetSite: Void CreateHandle(System.Windows.Forms.CreateParams)
HelpLink: NULL
Source: System.Windows.FormsStackTrace Information
*********************************************
в System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
в System.Windows.Forms.Control.CreateHandle()
в System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
в System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
в System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
в System.Windows.Forms.Control.CreateControl()
в System.Windows.Forms.Control.ControlCollection.Add(Control value)
в MD.ControlArray.AddNewButton(Int32 topPos, Int32 leftPos, Details lICFCode) в F:ProjectsMDMDClassesControlArray.cs:строка 50
в MD.FormVorschau.AddNewICFControl(Details lICFCode) в F:ProjectsMDMDFormVorschau.cs:строка 828
в MD.FormVorschau.FillListOfCodeControls() в F:ProjectsMDMDFormVorschau.cs:строка 851####################################################################################################################
Сразу обмолвлюсь, что форму создавал другой человек, которого уже не найти
. Ессно клиент переделывать во что-то более внятное не хочет, потому у меня есть несколько вопросов:
1. Ошибка возникает потому что не хватает памяти, или дескрипторов окна?
2. Что можно сделать для убыстрения формы, или хотя бы устранения подобной ошибки?
3. Где можно внятно почитать об особенностях ControlCollection?
«Ошибка при создании дескриптора окна» — была такая проблема при использовании SourceGrid (в ней под каждую ячейку создавалось окно) — устранил путём уменьшения показываемых строк. Видимо и здесь их количество (репитеров) нужно уменьшить. Может фильтры какие-нибудь на выборку записей из БД задать.
Здравствуйте, andrewr, Вы писали:
A>Exception Information
A>*********************************************
A>Exception Type: System.ComponentModel.Win32Exception
A>NativeErrorCode: 8
Так. Если я правильно понимаю, то «NativeErrorCode: 8» — это ERROR_NOT_ENOUGH_MEMORY.
A>Сразу обмолвлюсь, что форму создавал другой человек, которого уже не найти. Ессно клиент переделывать во что-то более внятное не хочет, потому у меня есть несколько вопросов:
A>1. Ошибка возникает потому что не хватает памяти, или дескрипторов окна?
Скорее всего слишком много дескрипторов. Правда я с этим не сталкивался.
A>2. Что можно сделать для убыстрения формы, или хотя бы устранения подобной ошибки?
Виртуализовать. Пользователь же не все 900 контролов видит одновременно. Еще вариант, попробовать реализовать некоторые контролы без хэндла — просто как графический элемент (если такое возможно, конечно).
A>3. Где можно внятно почитать об особенностях ControlCollection?
Да нет там особенностей. Обычная строго-типизированная коллекция, выполняющая всякие служебные функции, типа прописывания Parent-а.
Здравствуйте, MxMsk, Вы писали:
MM>Здравствуйте, andrewr, Вы писали:
A>>Exception Information
A>>*********************************************
A>>Exception Type: System.ComponentModel.Win32Exception
A>>NativeErrorCode: 8
MM>Так. Если я правильно понимаю, то «NativeErrorCode: 8» — это ERROR_NOT_ENOUGH_MEMORY.
Ага. Наконец то я уверен в этой ошибке
A>>Сразу обмолвлюсь, что форму создавал другой человек, которого уже не найти. Ессно клиент переделывать во что-то более внятное не хочет, потому у меня есть несколько вопросов:
A>>1. Ошибка возникает потому что не хватает памяти, или дескрипторов окна?
MM>Скорее всего слишком много дескрипторов. Правда я с этим не сталкивался.
Ну реально на кастом контроле около 5 лейблов, которые ессно создают свой дескриптор окна. Сейчас я переубеждаю клиента в том, что нужно эти лейблы менять на овн-дравинг.
A>>2. Что можно сделать для убыстрения формы, или хотя бы устранения подобной ошибки?
MM>Виртуализовать. Пользователь же не все 900 контролов видит одновременно. Еще вариант, попробовать реализовать некоторые контролы без хэндла — просто как графический элемент (если такое возможно, конечно).
В том то и дело, что для виртуализации нужно делать оч много переделок самой формы. Она изначально была сделана без учета подобных проблем, да и раньше надо было загружать не более 10-12 элементов. Как я сказал выше, буду продавливать замену всех лишних контролов на их отрисовку. Там даже чекбокс можно на отрисованный поменять без особой внешней разницы.
В целом все ясно. Тему можно закрывать. Спасибо откликнувшимся.
Мы наблюдаем эту ошибку в приложении 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)
leora, 21 октября 2008 г., 21:01
67
109 867
10
Ответы:
Я думаю, это обычно связано с тем, что компьютеру не хватает памяти, поэтому он не может создавать больше оконных дескрипторов. Обычно в этот момент окна тоже начинают показывать странное поведение.
AtliB, 21 октября 2008 г., 21:13
Решено
Вы запускали Process Explorer или диспетчер задач Windows, чтобы просматривать объекты GDI, дескрипторы, потоки и объекты USER? Если нет, выберите эти столбцы для просмотра (в диспетчере задач выберите «Просмотр» -> «Выбрать столбцы» … Затем запустите приложение, посмотрите на эти столбцы для этого приложения и посмотрите, действительно ли один из них становится большим.
Возможно, у вас есть компоненты пользовательского интерфейса, которые вы очистили считать, но не были удалены.
Вот ссылка об этом может быть полезно.
Удачи!
itsmatt, 21 октября 2008 г., 22:06
Предложение о нехватке памяти не похоже на плохую зацепку.
Что делает ваша программа, чтобы получить эту ошибку?
Создает много окон или элементов управления?
Создает ли он их программно, а не во время разработки?
Если да, то делаете ли вы это в цикле? Этот цикл бесконечен?
Вы потребляете ошеломляющие количества памяти каким-то другим способом?
Что происходит, когда вы смотрите, какая память используется вашим приложением в диспетчере задач? Он взлетает до Луны? Или еще лучше, как было предложено выше, используйте монитор процесса, чтобы погрузиться в детали.
rice, 21 октября 2008 г., 22:11
Предел дескрипторов Windows для вашего приложения составляет 10 000 дескрипторов. Вы получаете сообщение об ошибке, потому что ваша программа создает слишком много дескрипторов. Вам нужно будет найти утечку памяти. Как предлагали другие пользователи, используйте профилировщик памяти. Я также использую .Net Memory Profiler. Кроме того, убедитесь, что вы вызываете метод dispose для элементов управления, если вы удаляете их из формы до, форма закрывается (в противном случае элементы управления не будут удалены). Вам также необходимо убедиться, что в элементе управления не зарегистрировано никаких событий. У меня такая же проблема, и, несмотря на то, что я уже знаю, у меня все еще есть утечки памяти, которые продолжают ускользать от меня …
mjezzi, 22 ноября 2008 г., 00:38
См. этот мой пост об «Ошибка создания дескриптора окна» и его отношение к объектам USER и куче рабочего стола. Предлагаю несколько решений.
Fabrice, 8 августа 2009 г., 04:35
У меня такая же ошибка в моем приложении. Я загружаю много элементов управления на одной странице. В событии нажатия кнопки я очищаю элементы управления. Очистка элементов управления не освобождает элементы управления из памяти. Поэтому удалите элементы управления из памяти.
Я просто прокомментировал метод controls.clear () и добавил несколько строк кода для удаления элементов управления.
Что-то вроде этого
Для каждого ctl в качестве элемента управления в коллекции controlcollection
Ctl.dispose ()
Следующий
honey0987, 1 сентября 2009 г., 23:10
Эта проблема почти всегда связана с количеством объектов GDI, пользовательских объектов или обработчиков и обычно нет из-за нехватки памяти на вашем компьютере.
Когда я отслеживаю одну из этих ошибок, я открываю ProcessExplorer и смотрю эти столбцы: дескрипторы, потоки, объекты GDI, объекты USER, частные байты, виртуальный размер и рабочий набор.
(По моему опыту, проблема обычно заключается в утечке объекта из-за того, что обработчик событий удерживает объект и препятствует его удалению.)
AlfredBr, 8 февраля 2010 г., 17:36
Что ж, в моем случае именно объекты USER вышли из-под контроля. Я заглянул в диспетчер задач Windows и, конечно же, количество объектов USER было ровно 10’000.
Я динамически встраиваю листы свойств и списков в страницы вкладок, устанавливая для свойства Parent свойства или панели контейнера листа списка значение страницы вкладок. Я условно рециркулирую или повторно создаю формы листа свойств и списка в зависимости от типа перечисляемой коллекции или типа класса проверяемого объекта.
NB: В Delphi у всех элементов управления были свойства Owner и Parent. Даже если изменить свойство Parent элемента управления, он все равно будет удален его владельцем, когда элемент управления-владелец будет уничтожен.
В C# кажется, что если элемент управления, например, Панель программно переназначается, скажем, из формы на страницу вкладки путем изменения свойства Panel.Parent, вызов Dispose () в форме не удаляет панель, как и вызов Controls.Clear () на странице вкладок. Даже прямой вызов Panel.Dispose () на самом деле не удалит его, если для его Parent заранее вручную не установлено значение null.
kingsley, 18 марта 2010 г., 15:38
Определенно слишком много дескрипторов (проблема с утечкой памяти):
IT-джунгли: System.ComponentModel.Win32Exception: ошибка при создании дескриптора окна
user344760, 1 июня 2010 г., 06:25
Я добавил проверку, которая заставляет работать …
if (_form.Handle.ToInt32() > 0)
{
_form.Invoke(method, args);
}
Это всегда верно, но без этого форма выдает ошибку.
Кстати, моя ручка составляет около 4,9 миллиона
xlthim, 21 марта 2012 г., 23:32