Domanda

Ho un serio testa-scratcher sulle mie mani qui. Sto indagando problemi di prestazioni con un componente WPF nella nostra applicazione.

Il nostro .net applicazione è molto grande, e quasi interamente in Windows Forms. Come parte di una nuova iniziativa abbiamo riscritto una delle nostre componenti del centro con una ricca interfaccia utente WPF. C'è un sacco di WinForms <->. WPF interoperabilità succedendo con questa cosa per incollare insieme, e ho il sospetto che possa essere in qualche modo legato a quello che sto vedendo

Quando ho Profilo La lenta operazione di ANTS Profiler, vedo un sacco di attività che si verificano all'interno della funzione UnsafeNativeMethods.IntGetMessageW. ANTS rapporti quanto più l'attività della CPU andare lì come fa a tutti i nostri logica di business e WPF rendendo roba combinato. Non v'è alcun codice gestito a valle di quella funzione che utilizza i cicli, in modo da qualunque IntGetMessageW sta facendo lì è quello che sto cercando.

Non sto particolarmente ben versato in Win32 programmazione, ma so che le basi di un ciclo di messaggi in quel contesto. Niente di quello che sto vedendo qui è però tutto quello che facciamo manualmente - in nessun punto nel nostro codice stiamo interagendo direttamente sia con il sottostante MessageLoop stesso, o una qualsiasi delle cose più complicato che può essere letta sul dispatcher WPF.

componente nostra WPF in questione qui è scritto che eredita da finestra (cioè. Non è solo un controllo / UserControl), e noi vederlo utilizzando ShowDialog dalla nostra logica di più alto livello che ha usato per chiamare ShowDialog sulla versione vecchia WinForms di questo componente. Ci sono alcuni controlli WindowsFormsIntegrationHost che abbiamo usato all'interno del componente WPF per mantenere la compatibilità con alcuni dei nostri pezzi esistenti che non potevano essere riscritto in WPF.

Sono stato alla ricerca per giorni, ma non hanno mai trovato un bel po 'per andare avanti. Io continuo a trovare messaggi vagamente correlate che parlare di messaggi di input (mouse e tastiera), ma non so che cosa posso fare per verificare che; Ho già provato macellazione il codice per rimuovere ogni operazione mouse / tastiera che potevo.

Sto avendo un momento difficile ottenere da nessuna parte in primo luogo perché questa riga di codice è completamente isolato (non un genitore o un figlio di qualcosa che posso sottolineare come in realtà provenienti dal nostro codice), e completamente opaco su ciò che sta facendo.

Ecco un'immagine di un grafico ANTS chiamata della funzione ShowDialog che mostra il percorso di chiamate per arrivare qui: alt text

Mi rendo perfettamente conto che questo potrebbe essere qualcosa che deve solo essere fatto come parte di WPF (anche se altri componenets che abbiamo scritto in WPF non visualizzano questo comportamento), o che questo è solo uno strano bug in ANTS Profiler , ma a questo punto ho bisogno di verificare in un modo o in un altro. Se qualcuno mi può dire che cosa è o potrebbe essere succedendo qui -. O indicarlo in qualche modo sarei stato in grado di capirlo io stesso, voglio dirigere tutti i tipi di buon karma tua strada

UPDATE: In risposta a qualche discussione che segue, qui è un'altra vista dalle formiche - questo uno migliore illustra la confusione che sto avendo (questo è con le formiche visualizzazione in modalità "CPU tempo"). Ho fretta censurato parti del nostro codice, ma nessuna delle funzioni relative di sistema:

alt text

Grazie per guardare!

È stato utile?

Soluzione

Ho trovato questo durante la ricerca di informazioni sullo stesso argomento. Io aggiungo quello che so e vedere se aiuta:

Sono in esecuzione su una scatola di WinXP - il quadro WPF è più integrato in Vista e Win7 quanto lo sia in XP. Alcune di queste potrebbero essere causa di come WPF corre "in primo piano" del desktop XP, piuttosto che all'interno di esso.

Io corro una pura applicazione WPF nativa -. Senza WinForms o altro codice

mi sono imbattuto in questo cercando di determinare perché semplicemente scorrendo una finestra consumerebbe 100% della CPU e balbuzie allo stesso tempo.

L'esecuzione del profiler prestazioni AQtime, vedo che IntGetMessageW occupa la maggior parte di questo utilizzo della CPU al 100%. Ciò non è dovuto a IntGetMessageW in attesa di un messaggio, ma qualcosa la funzione è in realtà facendo.

L'unica cosa che non ho guardato in ancora è che forse IntGetMessageW non è mai stato un metodo veloce, e forse WPF semplicemente un utilizzo eccessivo di esso. E 'possibile che associazioni di dati in WPF utilizzare la pompa nativo messaggio Win32 per aggiornare le proprietà di dipendenza all'interno di WPF. Se questo è il caso, potrebbe essere che la mia finestra ha semplicemente troppi attacchi.

Altri suggerimenti

Sì, questo è normale. Qualsiasi GUI app è sempre esecuzione GetMessageW (), in attesa di Windows per inviare un messaggio. Non viene effettivamente bruciando cicli di CPU questo modo, semplicemente bloccato su un oggetto sincronizzazione interna finché viene segnalato qualche tipo di evento UI.

Questo naturalmente rende profiling UI apps difficile, si ha realmente bisogno di unit test che prova i sottocomponenti della vostra applicazione.

Quando il profiling di un'applicazione, è necessario distinguere tra il tempo speso in un metodo e cicli di CPU consumato. Molti strumenti di profiling si lo spettacolo tempo complessivo trascorso in un metodo - che nel caso di somthing come GetMessageW sta per essere molto elevato. Tutte le attività del thread principale di un'applicazione GUI apparirà per accadere all'interno di tale metodo. Questo non è necessariamente un problema, però ... questo può essere semplicemente la pompa principale messaggio in attesa su un oggetti di sincronizzazione e in realtà non consumano cicli.

vorrei suggerire di iniziare con la funzione di campionamento nelle ANTS Profiler per identificare i metodi che vengono chiamati il più delle volte e correlare quelli ai metodi che stanno consumando il maggior numero di cicli di CPU. una volta fatto questo, si decide dove strumento l'applicazione per immersione in più e avere un'idea di ciò che i grafici di chiamata assomigliano per i luoghi che sono più impegnativo per la CPU.

si dovrebbe iniziare a sospettare il proprio codice prima. E 'raro che qualcosa come l'infrastruttura WPF o Win32 è responsabile per scarso rendimento o elevato utilizzo della CPU. Probabilmente, le bugie problema da qualche parte nella vostra applicazione -. Ti aiuterà a raggiungere un senso generale di cui cicli di CPU sono spesi nel programma

Ti suggerisco anche di trascorrere qualche ora apprendere le funzionalità del profiler per essere più efficace. Profilers può essere sofisticato e strumenti confusione fino a quando non capire che cosa è che stanno cercando di mostrare. Il tutoral collegato da Redgate dovrebbe essere un buon posto per iniziare, se non l'avete già fatto. Ad esempio, la visualizzazione temporale può effettivamente essere un buon punto di partenza per vedere dove l'attività alta CPU si verifica, e confinare l'analisi a quei segmenti di codice eseguito.

alt text

Il Call Graph è un altro strumento utile di formiche, come ti aiuta a drill in aree di codice che sono più costosi. La chiave è quello di assicurarsi che si sta guardando il costo complessivo e non solo il tempo complessivo .

alt text

Sembra che il tuo messaggio pompa sta pompando molto. Potrebbe essere interessante vedere che tipo di messaggio il vostro coda dei messaggi è piena di. Si può utilizzare Spy ++ sulla vostra finestra per vedere cosa sta succedendo?

Modifica

ho frainteso il problema.

Hans Passant è giusto, il vostro programma è solo in attesa su GetMessage per qualche evento al processo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top