Система.ComponentModel.Win32Exception:Операция завершилась успешно

StackOverflow https://stackoverflow.com/questions/1209769

Вопрос

Иногда я получаю это исключение при длительном запуске моего приложения Windows Forms:

System.ComponentModel.Win32Exception: The operation completed successfully
   at System.Drawing.BufferedGraphicsContext.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)
   at System.Drawing.BufferedGraphicsContext.CreateBuffer(IntPtr src, Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)
   at System.Drawing.BufferedGraphicsContext.AllocBuffer(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at System.Drawing.BufferedGraphicsContext.AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetRectangle)
   at System.Drawing.BufferedGraphicsContext.Allocate(IntPtr targetDC, Rectangle targetRectangle)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Что может быть причиной этого?

Это было полезно?

Решение

Подводя итог, я могу сказать, что пользовательская сетка, которую я написал, основана на DataGridView .Net's DataGridView, использует пользовательский код для рисования ячеек.Строки в моей сетке могут занимать несколько визуальных страниц.(Это было бизнес-требованием)

Проблема заключалась в том, что .Net предварительно выделяет буфер памяти для элементов управления с включенной двойной буферизацией.Для сеток DataGridViews буфер должен быть достаточно большим, чтобы вместить возможные большие строки в сетке.В крайних случаях строка может занимать до 32000 пикселей (из-за ограничения .net).Ширина сетки в проекте обычно составляет от 500 до 800 пикселей.Таким образом, результирующий буфер может быть (32 бит /с * 800 * 32000 = ~ 100 МБ)

Короче говоря, система не могла создавать совместимые графические объекты, потому что иногда она не могла зарезервировать буфер, достаточно большой, чтобы вместить необходимые данные.

Чтобы исправить это, мне пришлось ввести ряд оптимизаций:

  • максимальная разрешенная высота строки в моей пользовательской сетке ограничена 1500 пикселями
  • обновленный код перераспределения буфера, который будет выполняться только тогда, когда размер нового буфера будет больше существующего
  • гарантировано, что буферы не перераспределяются при каждой привязке данных, а предварительно распределяются до разумного размера.
  • просмотрел весь код и убедился, что неуправляемые ресурсы правильно утилизируются, когда они не используются, как рекомендовано здесь: http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html

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

В Windows жесткое ограничение составляет 10000 дескрипторов на процесс. Довольно бесполезное исключение " Операция успешно завершена " может указывать на то, что этот предел достигнут.

Если это произошло из-за утечки ресурсов в вашем коде, то вам повезло, поскольку у вас по крайней мере есть возможность исправить свой код.

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

Несколько полезных ссылок:

http://support.microsoft.com/kb/327699 http://nomagichere.blogspot.com/2008/03/systemcomponentmodelwin32exception-is.html

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

У меня была такая же проблема в VB.NET. Причина этого была странной:

В Австрии наши системы Windows обычно имеют запятую и a. как тысячи сепаратор. Если это искажено (что является стандартным в США, я думаю), Windows выдаст эту ошибку. Изменение его в Австрии должно быть решено ...

Удачи!

Нашел этот , который может помочь - кажется, это графика или контролировать вопрос утилизации

Это вызвано в крайних случаях неиспользованием изображений. Вы должны использовать IDisposable при загрузке растровых изображений, чтобы преодолеть это;

using(Bitmap b = Bitmap.FromFile("myfile.jpg"))
{
   //Do whatever
}

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

Кроме того, утечки памяти могут вызвать исключение. Например, приложение с 2-3 веб-браузерами может занять более 1 ГБ за несколько минут из-за одной из ошибок интернет-обозревателя, например это .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top