2009-07-30 4 views
21

я получаю это исключение иногда во время работы моей Windows Forms приложения в течение длительного времени:System.ComponentModel.Win32Exception: Операция успешно завершена

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) 

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

+5

Я нахожу 1400 хитов в Google об этом, но ничего похожего на реальное объяснение. – Niki

ответ

19

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

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

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

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

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

Good Guy Greg on stackoverflow: решает собственную проблему, ПОСТ-РЕШЕНИЕ. – matao

+1

Хороший анализ, но хотелось бы увидеть фрагмент кода и еще несколько пояснений относительно «серии оптимизаций». – ra170

+0

Хорошая точка, ra170, я редактировал вопрос и перечислял шаги, которые ранее были описаны как «серия оптимизаций». Благодаря! –

2

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

1

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

2

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

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

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

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

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

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

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

+0

10000 Ручки за процесс? Это новое и безумное, есть ли способ увеличить этот предел? –

+0

@AkashKava Это ограничение не нова - я мог ошибаться, но я думаю, что это было с Windows NT. И он встроен в кодовую базу ОС и не может быть изменен извне. –

+0

Я согласен с процессом, который превысил дескрипторы 10k, и когда я пытаюсь создать новый визуал WPF (var visual = new DrawingVisual()), я получаю вышеупомянутую ошибку. –

3

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

3

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

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

Удачи!

0

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

Смежные вопросы