La comprensión de este error
Superación de los límites de las ventanas: de usuario y objetos GDI - Parte 1 de Mark Russinovich: https://blogs.technet.microsoft.com/markrussinovich/2010/02/24/pushing-the-limits-of-windows-user-and-gdi-objects-part-1/
solucionar este error
Necesita ser capaz de reproduce el problema Aquí hay una forma de registrar los pasos para hacer eso https://stackoverflow.com/a/30525957/495455.
La manera más fácil de resolver qué está creando tantos controles es tener TaskMgr.exe abierto. En Taskmgr.exe es necesario tener el objeto de usuario, GDI y objetos Maneja columnas visibles, como se muestra, para ello seleccione el menú Vista> Seleccionar columnas:
ir a través de los pasos para la causa del problema y el reloj el recuento de objetos del USUARIO aumenta a alrededor de 10.000 o los objetos o asas GDI alcanzan sus límites.
Cuando vea que el Objeto o los Controles aumentan (típicamente de forma espectacular) puede detener la ejecución del código en Visual Studio haciendo clic en el botón Pausa.
Luego, mantenga presionada la tecla F10 o F11 para recorrer el código y ver cuando el recuento de objetos/asa aumenta dramáticamente.
La mejor herramienta que he encontrado hasta ahora es GDIView de NirSoft, se rompe el IDG Handle campos:
que lo rastreó a este código utilizado al establecer anchos de columna DataGridViews:
If Me.Controls.ContainsKey(comboName) Then
cbo = CType(Me.Controls(comboName), ComboBox)
With cbo
.Location = New System.Drawing.Point(cumulativeWidth, 0)
.Width = Me.Columns(i).Width
End With
'Explicitly cleaning up fixed the issue of releasing USER objects.
cbo.Dispose()
cbo = Nothing
End If
Este es el seguimiento de la pila:
en System.W indows.Forms.Control.CreateHandle() en System.Windows.Forms.ComboBox.CreateHandle() en System.Windows.Forms.Control.get_Handle() en System.Windows.Forms.ComboBox.InvalidateEverything() en System.Windows.Forms.ComboBox.OnResize (EventArgs e) en System.Windows.Forms.Control.OnSizeChanged (EventArgs e) en System.Windows.Forms.Control.UpdateBounds (Int32 x, Int32 y, Int32 ancho, altura Int32, Int32 clientWidth, Int32 clientHeight) en System.Windows.Forms.Control.UpdateBounds (Int32 x , Int32 y, Int32 anchura, altura Int32) en System.Windows.Forms.Control.SetBoundsCore (Int32 x, Int32 y, Int32 anchura, altura Int32, BoundsSpecified especificado) en System.Windows.Forms.ComboBox.SetBoundsCore (Int32 x, Int32 y, Int32 ancho, altura Int32, BoundsSpecified especificado) en System.Windows.Forms.Control.SetBounds (ancho Int32 x, Int32 y, Int32, alto Int32, BoundsSpecified especificado) en System.Windows .Forms.Control.set_Width (Int32 val ue)
Aquí es el quid de a helpful article by Fabrice que me ayudó a trabajar en los límites:
"identificador de ventana Error creando"
Cuando una gran aplicación de Windows Forms que estoy trabajando para un cliente se usa activamente, los usuarios a menudo obtienen excepciones de "Error al crear el identificador de ventana".
Aparte del hecho de que la aplicación consume demasiados recursos, lo cual es un tema aparte por completo que ya estamos abordando, hemos tenido dificultades con la determinación de qué recursos se estaban agotados, así como cuáles son los límites de estos recursos. Primero pensamos en vigilar el contador de Controles en el Administrador de tareas de Windows. Eso fue porque notamos que algunos procesos tendían a consumir más de estos recursos de lo que normalmente deberían. Sin embargo, este contador no es el correcto porque hace un seguimiento de recursos como archivos, sockets, procesos e hilos. Estos recursos se denominan objetos Kernel.
Los otros tipos de recursos que debemos tener en cuenta son los objetos GDI y los objetos del usuario. Puede obtener una descripción general de las tres categorías de recursos en MSDN.
usuario Objetos
problemas de creación de la ventana están directamente relacionados con Objetos de usuario.
Intentamos determinar cuál es el límite en términos de objetos de usuario que una aplicación puede usar. Hay una cuota de 10.000 identificadores de usuario por proceso. Este valor se puede cambiar en el registro, sin embargo, este límite no fue el verdadero obstáculo en nuestro caso. El otro límite es 66.536 identificadores de usuario por sesión de Windows. Este límite es teórico. En la práctica, notará que no se puede alcanzar. En nuestro caso, recibíamos la temida excepción "Error al crear el identificador de ventana" antes de que la cantidad total de Objetos de usuario en la sesión actual alcanzara los 11,000.
montón de escritorio
Entonces descubrimos qué límite era el verdadero culpable: era el "montón de escritorio". De forma predeterminada, todas las aplicaciones gráficas de una sesión de usuario interactiva se ejecutan en lo que se denomina "escritorio". Los recursos asignados a dicho escritorio son limitados (pero configurables).
Nota: Los objetos de usuario son los que consumen la mayor parte del espacio de memoria del montón de escritorio. Esto incluye ventanas. Para obtener más información acerca del Desktop Heap, puede consultar los muy buenos artículos publicados en el blog NTDebugging MSDN:
¿Cuál es la verdadera solución? ¡Ser verde!
Incrementar Desktop Heap es una solución efectiva, pero no es la mejor. La solución real es consumir menos recursos (menos controladores de ventanas en nuestro caso). Puedo adivinar lo decepcionado que puede estar con esta solución. ¿Es esto realmente todo lo que puedo pensar? Bueno, no hay un gran secreto aquí. La única salida es ser delgado. Tener UI menos complicadas es un buen comienzo. Es bueno para los recursos, también es bueno para la usabilidad. El siguiente paso es evitar el desperdicio, preservar los recursos y reciclarlos.
Aquí es cómo lo estamos haciendo esto en la solicitud de mi cliente:
Utilizamos TabControls y creamos el contenido de cada pestaña sobre la marcha, cuando se hace visible; Utilizamos regiones expandibles/plegables, y nuevamente las llenamos con controles y datos solo cuando es necesario; Lanzamos recursos lo antes posible (utilizando el método Dispose). Cuando una región se colapsa, es posible borrar sus controles secundarios. Lo mismo para una pestaña cuando se oculta; Usamos el patrón de diseño MVP, que ayuda a hacer posible lo anterior porque separa los datos de las vistas; Usamos motores de diseño, los estándar FlowLayoutPanel y TableLayoutPanel, o personalizados, en lugar de crear jerarquías profundas de paneles anidados, GroupBoxes y Splitters (un divisor vacío en sí mismo consume tres controladores de ventana ...). Lo anterior son solo sugerencias de lo que puede hacer si necesita crear pantallas ricas de Windows Forms. No hay duda de que puedes encontrar otros enfoques. Lo primero que debe hacer en mi opinión es crear sus aplicaciones en casos de uso y escenarios. Esto ayuda a mostrar solo lo que se necesita en un momento determinado y para un usuario determinado.
Por supuesto, otra solución sería usar un sistema que no dependa de controladores ... ¿WPF a alguien?
Vea también [este artículo mío sobre "Error al crear el identificador de ventana"] [1] y cómo se relaciona con los Objetos USUARIO y el Heap de Escritorio. Proporciono algunas soluciones. [1]: http://weblogs.asp.net/fmarguerie/archive/2009/08/07/cannot-create-window-handle-desktop-heap.aspx – Fabrice