Подтвердить что ты не робот

System.ComponentModel.Win32Exception: операция успешно завершена

Я иногда получаю это исключение при запуске приложения 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)

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

Некоторые полезные ссылки:

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

Ответ 3

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

Ответ 4

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

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

Удачи!

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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