2011-11-14 7 views
10

Por lo tanto, estoy experimentando un problema muy extraño con mi pequeña aplicación de prueba. Y por cuestión, me refiero a que se bloquea ... difícil. No se lanza ninguna excepción (al menos, nada que yo pueda atrapar), solo el mensaje "Blah Blah ha dejado de responder ...". Se bloquea SOLO cuando ejecuto la aplicación en x64, modo de lanzamiento y fuera del IDE. Si lo ejecuto en modo x86, o si lo ejecuto en el IDE en x64 o lo ejecuto de forma independiente como DEPURACIÓN en x64, funciona bien.Bloqueo con una aplicación x64 .NET 4.0 en modo de lanzamiento fuera del IDE solamente

Lo he reducido a mi llamada p/invocar PeekMessage. Entonces, necesito que las mentes brillantes aquí miren la porquería que escribí y me digan si lo estoy haciendo bien. Porque, en serio, estoy a punto de perder la cabeza. Lo intenté en 2 computadoras y ambos muestran el mismo comportamiento. Estoy un poco preocupado de que esto podría ser un error de .NET 4.0.

De todos modos, aquí está mi código p/invoke. Por favor, hágamelo saber si usted ve algo raro o simplemente estúpido:

Aquí está la llamada a PeekMessage:

private static bool PeekMessage() 
{ 
     MSG message = new MSG();    // Message to retrieve. 

     return Win32API.PeekMessage(ref message, IntPtr.Zero, 0, 0, PeekMessageFlags.NoRemove); 
} 

Aquí es PeekMessage (NOTA: El atributo de seguridad de supresión está en la definición de clase, por lo que se está aplicada):

[return: MarshalAs(UnmanagedType.Bool)] 
[DllImport("User32.dll", CharSet=CharSet.Auto)] 
public static extern bool PeekMessage(ref MSG msg, IntPtr hwnd, uint wFilterMin, uint wFilterMax, PeekMessageFlags flags); 

Aquí está el MSG:

[StructLayout(LayoutKind.Sequential)] 
internal struct MSG 
{ 
     /// <summary>Window handle.</summary> 
     public IntPtr hwnd; 
     /// <summary>Message to process.</summary> 
     public uint Message; 
     /// <summary>Window message parameter 1.</summary> 
     public uint wParam; 
     /// <summary>Window message parameter 2.</summary> 
     public uint lParam; 
     /// <summary>Time message was sent?</summary> 
     public uint time; 
     /// <summary>Mouse pointer position.</summary> 
     public Point pt; 
} 

Y, por último, la PeekMessageFlags:

internal enum PeekMessageFlags 
{ 
     /// <summary>Keep message on the message queue.</summary> 
     NoRemove = 0, 
     /// <summary>Remove message from the queue.</summary> 
     Remove = 1, 
     /// <summary>Do not yield execution to waiting threads.</summary> 
     NoYield = 2 
} 

Comprobé el registro de eventos y tengo este:

Faulting application name: Tester_Graphics.exe, version: 1.0.0.0, time stamp: 0x4ec0ba85 
Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000 
Exception code: 0xc0000005 
Fault offset: 0x00000000000001cb 
Faulting process id: 0x1260 
Faulting application start time: 0x01cca299e2c21a77 
Faulting application path: D:\Code\Current\Gorgon\Branches\2.x\Dorian\Examples\Tester_Graphics\bin\Release\Tester_Graphics.exe 
Faulting module path: unknown 
Report Id: 20ac891f-0e8d-11e1-a5d7-bcaec5753ddd 

Por lo tanto, si ves algo que no está bien, por favor hágamelo saber. Odiaría que esto no fuera culpa mía.

Lo siento si no se detalla lo suficiente, si necesita más información, simplemente deje una nota.

+1

Tuve problemas similares incluso con los más mínimos parámetros incorrectos, especialmente las cadenas (Unicode vs. Ansi, etc.) [Esta página] (http://www.pinvoke.net/default.aspx/user32.peekmessage) enumera una diferente firma para 'PeekMessage'. Te sugiero que pruebes varios otros hasta que encuentres uno. –

+2

Como nota al azar, si tenía problemas para depurar esto, causaba la excepción. Suponiendo que pueda cargar su programa después de haberlo creado, puede ejecutarlo. Luego, el estudio visual habitual se conecta al proceso y usted debería poder depurarlo incluso en modo de liberación, siempre que los PDB estén con él. Luego puedes activar el break en cualquier excepción lanzada (CTRL + ALT + E) y probablemente habrás obtenido mucha más información. –

+0

Sí, consideré hacer eso, pero fue una excepción de inmediato, así que no había tiempo para adjuntarme. Ahora me doy cuenta de que podría haber agregado un retraso de "Sueño" antes del "Mensaje de Peek", pero era medianoche y apenas pude formar oraciones coherentes, por lo que no se me ocurrió en ese momento. – Mike

Respuesta

6

El tamaño de lParam y wParam campos de MSG son incorrectos. Debe usar IntPtr en lugar de uint/int.

Si se echa un vistazo a Windows Data Types se puede ver que:

  • LPARAM es una LONG_PTR es decir, sus 32 bits de tamaño de las plataformas de 32 bits y 64 bits de tamaño en las plataformas de 64 bits.
  • PARAM es un UINT_PTR que nuevamente tiene 32 bits en el tamaño de las plataformas de 32 bits y 64 bits en las plataformas de 64 bits.

el contrario los int y uint tipos son ambos de 32 bits de tamaño independientemente de la plataforma, lo que significa que en las plataformas de 64 bits MSG su estructura es de 64 bits demasiado pequeñas que dará lugar a algún tipo de corrupción de memoria.

+2

Sí, acabo de ver esto después de que Uwe Keim me sugirió que visite pinvoke.net. Lo había hecho anoche. Lo cambié a 'IntPtr' y funcionó a las mil maravillas. Así que gracias a los dos. – Mike

Cuestiones relacionadas