c# - sistema - Win32Exception No hay suficiente almacenamiento disponible para procesar este comando
no hay suficientes recursos de memoria disponible para procesar este comando (4)
El problema probablemente no se encuentra en su WndProc, la razón por la que lo ve en sus pilas de llamadas es porque prácticamente todo lo relacionado con GUI en Windows pasa por el procedimiento de ventana de WIN32. Anularlo en su control simplemente le da un punto de enlace para procesar cosas de bajo nivel antes de que se realice el procesamiento de .NET Framework de nivel superior.
Esta va a ser una toma completa en la oscuridad, pero tal vez esta publicación podría ser relevante? Sin embargo, probablemente no con esos rastros de pila.
A través de mi colección automática automatizada para MaxTo obtuve el siguiente informe de fallos :
V8.12.0.0 - System.ComponentModel.Win32Exception - :Void UpdateLayered():0
Version: MaxTo8.12.0.0
Exception: System.ComponentModel.Win32Exception
Error message: Not enough storage is available to process this command
Stack trace:
at System.Windows.Forms.Form.UpdateLayered()
at System.Windows.Forms.Form.OnHandleCreated(EventArgs e)
at System.Windows.Forms.Control.WmCreate(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmCreate(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at MaxTo.MainForm.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)
Otra stacktrace:
Version: MaxTo2009.9.0.0
Exception: System.ComponentModel.Win32Exception
Error message: Not enough storage is available to process this command
Stack trace:
at System.Windows.Forms.Form.UpdateLayered()
at System.Windows.Forms.Form.OnHandleCreated(EventArgs e)
at System.Windows.Forms.Control.WmCreate(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmCreate(Message& m)
at System.Windows.Forms.Form.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)
En este último rastro de pila no hay ninguna referencia a MaxTo en absoluto, y el 90% de los bloqueos que obtengo tienen rastros de pila similares a los anteriores.
Leyendo en la red encuentro que este error es habitual si olvida liberar o eliminar variables. Al mirar a través de mi WndProc
, que a veces parece tener el problema, no puedo encontrar un solo lugar que cuelgue de referencias a cualquier objeto. Todas menos una de las variables son locales para WndProc y, por lo tanto, deberían ser basura cuando el método finaliza.
protected override void WndProc(ref Message m)
{
base.WndProc(ref m); // I''m assuming the first trace can be caught here
IntPtr hwnd = m.WParam;
// Our hook tells us something got maximized
if (Win32Import.UWM_MAXIMIZE == (UInt32)m.Msg)
{
// Figure out if we are temporarily disabled or using alternative profiles
KeyStateInfo keyState = KeyboardInfo.GetKeyState(Settings.AlternativeProfileKey);
Rectangle r = FindRectangle(MousePosition, (Settings.EnableAlternativeProfile && keyState.IsPressed ? AlternativeRegions : Regions));
// Did we find a rectangle to place it in?
if (r != Rectangle.Empty)
{
Rectangle position = Win32Import.GetWindowRectangle(hwnd);
Rectangle previousPos = GetLocation(hwnd);
if (position == r && previousPos != Rectangle.Empty)
{
// We are restoring the original position
Win32Import.SetWindowPos(hwnd, IntPtr.Zero, previousPos.X, previousPos.Y, previousPos.Width, previousPos.Height, Win32Import.SWP_NOZORDER | Win32Import.SWP_NOSENDCHANGING);
}
else
{
// We are maximizing to a region
Win32Import.ShowWindow(hwnd, Win32Import.WindowShowStyle.Restore);
Win32Import.SetWindowPos(hwnd, IntPtr.Zero, r.X, r.Y, r.Width, r.Height, Win32Import.SWP_NOZORDER | Win32Import.SWP_NOSENDCHANGING);
// Make sure we remember this location
RememberLocation(hwnd, position);
}
}
}
else if (MaxTo64WindowHandleMessage == m.Msg)
{
// Store the window handle of our 64-bit subprocess
SubProcess64WindowHandle = m.WParam;
}
}
No he podido reproducir el error, incluso al ejecutar el programa durante varios días.
Mi suposición es que el sistema tiene poca memoria no fragmentada o controladores GDI, pero no puedo confirmarlo en ninguna parte. No parece haber ninguna buena documentación sobre este error.
¿Alguna idea de qué más podría ser? ¿Puedo hacer algo para evitar este error?
Actualización : la pregunta se volvió a abrir con más seguimientos de pila, debido a la falta de una solución decente. Simplemente ignorarlo no resuelve el problema.
Fugas o uso de muchos objetos / controladores GDI. Esos podrían causar una escasez de recursos. Es posible que no pueda reproducirse porque sus usuarios pueden tener otros programas pesados de recursos de GDI en ejecución o usar Terminal Server, en cuyo caso tienen que compartir algo del montón con los otros usuarios. Ver error del sistema Código: 8. No hay suficiente almacenamiento disponible para procesar este comando
Aquí puede leer sobre la herramienta Desktop Heap Monitor para diagnosticar problemas de montón de escritorio.
Aquí y aquí y aquí están las herramientas de detección de fugas de GDI.
Su programa probablemente esté perdiendo recursos del kernel. Comience a diagnosticar este problema con Taskmgr.exe. Ver + Seleccionar columnas, verificar objetos de usuario, objetos GDI y Recuento de control. Ejecute su programa y observe si alguno de estos aumenta constantemente. Una vez que uno de ellos llegue a 10,000, su programa morirá.
Con una forma de ver rápidamente la fuga en acción, puede comenzar a comentar el código para ver dónde ocurre la fuga. Probablemente tiene algo que ver con su "gancho".
Tenía muchos controles de Windows personalizados con recursos propios, así que cuando creo muchos controles aparece este error. Para solucionar este problema hice el archivo de recursos en mi biblioteca y utilicé recursos externos en lugar de recursos en mi código de componente. Después de eso, mi excepción ya no está, ya probó con formularios 3 veces más abiertos y este error desapareció. Parece que es una solución.