Система.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)

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

8 ответов


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

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

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

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

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

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

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

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

полезные ссылки:

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


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


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

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

удачи!


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


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

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

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


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