2011-11-14 10 views
10

Quindi, ho riscontrato un problema molto strano con la mia piccola applicazione di test. E per problema, voglio dire che si blocca ... difficile. Nessuna eccezione (almeno, nulla che io possa catturare) viene lanciata, solo il messaggio "Blah Blah ha smesso di rispondere ...". Si blocca SOLO quando eseguo l'app in x64, modalità di rilascio e al di fuori dell'IDE. Se lo eseguo in modalità x86, o se lo eseguo nell'IDE in x64 o lo eseguo autonomamente come DEBUG in x64, funziona bene.Arresto anomalo di un'applicazione .NET 4.0 x64 in modalità di rilascio all'esterno dell'IDE solo

L'ho ristretto al mio p/invocare la chiamata PeekMessage. Quindi, ho bisogno che le menti brillanti qui guardino la merda che ho scritto e mi dica se lo sto facendo bene. Perché, seriamente, sto per perdere la testa. Ho provato questo su 2 computer ed entrambi mostrano lo stesso comportamento. Sono un po 'preoccupato che questo potrebbe essere un bug .NET 4.0.

In ogni caso, ecco il mio codice p/invoke. Per favore fatemi sapere se si vede qualcosa di strano o semplicemente stupido:

Ecco la chiamata a PeekMessage:

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

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

Ecco PeekMessage (NOTA: L'attributo di sicurezza sopprimere è sulla definizione di classe, in modo che si sta applicata):

[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); 

Ecco il 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; 
} 

E, infine, il 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 
} 

Ho controllato il registro eventi e ho ottenuto questo:

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 

Quindi, se si vede qualcosa che non va, per favore fatemelo sapere. Odio per questo non essere colpa mia.

Spiacente se non è abbastanza dettagliato, se avete bisogno di maggiori informazioni, basta lasciare una nota.

+1

Ho riscontrato problemi simili con anche i parametri errati, in particolare stringhe (Unicode vs. Ansi ecc.) [Questa pagina] (http://www.pinvoke.net/default.aspx/user32.peekmessage) elenca un diverso firma per 'PeekMessage'. Ti suggerisco di provare molti altri finché non ne trovi uno. –

+2

Come nota a caso, se si riscontrano problemi nel debug di questo ha causato l'eccezione. Supponendo che potresti caricare il tuo programma dopo averlo creato, potresti eseguirlo. Quindi il solito studio visivo si collega al processo e dovresti essere in grado di eseguirne il debug anche in modalità di rilascio finché i PDB sono con esso. Quindi potresti attivare l'interruzione su qualsiasi eccezione generata (CTRL + ALT + E) e probabilmente avresti ottenuto molte più informazioni. –

+0

Sì, ho pensato di farlo, ma ha subito un'eccezione, quindi non c'era il tempo di allegare. Ora mi rendo conto che avrei potuto aggiungere un ritardo 'Sleep' prima del' PeekMessage', ma era mezzanotte e stavo a malapena in grado di formare frasi coerenti, quindi non mi è venuto in mente in quel momento. – Mike

risposta

6

Le dimensioni dei campi lParam e wParam di MSG sono errate. È necessario utilizzare IntPtr anziché uint/int.

Se si dà un'occhiata a Windows Data Types si può vedere che:

  • LPARAM è un LONG_PTR vale a dire i suoi 32 bit nel formato di 32 piattaforme bit e 64 bit nel formato su piattaforme a 64 bit.
  • PARAM è un UINT_PTR che è di nuovo 32 bit di dimensioni di piattaforme a 32 bit e 64 bit di dimensioni su piattaforme a 64 bit.

Viceversa i tipi int e uint sono entrambi dimensione di 32 bits indipendentemente dalla piattaforma, il che significa che su piattaforme a 64 bit vostro MSG struct è di 64 bit troppo piccole che si tradurrà in una sorta di danneggiamento della memoria.

+2

Sì, l'ho appena visto dopo che Uwe Keim mi ha suggerito di visitare pinvoke.net. L'avevo fatto la scorsa notte. L'ho cambiato in 'IntPtr' e funzionava come un incantesimo. Quindi grazie a tutti e due. – Mike

Problemi correlati