Pregunta

Tengo una seria rascarse la cabeza en mis manos aquí. Estoy investigando los problemas de rendimiento con un componente de WPF en nuestra aplicación.

Nuestra .net aplicación es muy grande, y casi en su totalidad en formas de las ventanas. Como parte de una nueva iniciativa reescribimos uno de nuestros componentes básicos con una rica interfaz de usuario de WPF. Hay una gran cantidad de WinForms <->. WPF interoperabilidad pasando con esta cosa para pegar juntos, y sospecho que puede ser de alguna manera relacionado con lo que estoy viendo

Cuando el perfil de la operación lenta en las hormigas de perfiles, veo una gran cantidad de actividad que se produce dentro de la función UnsafeNativeMethods.IntGetMessageW. informes hormigas mucha actividad de la CPU ir allí como lo hace para toda nuestra lógica de negocio y WPF haciendo cosas combinado. No hay código de línea descendente se gestiona de esa función que utiliza los ciclos, así que lo que está haciendo IntGetMessageW no es lo que busco.

No estoy particularmente bien versado en la programación Win32, pero sé lo básico de un bucle de mensajes en ese contexto. Nada de lo que estoy viendo aquí, sin embargo es algo que hacemos de forma manual - en ningún momento de nuestro código estamos interactuando directamente con el subyacente sea messageloop sí mismo, o cualquiera de las cosas más complicadas que se puede acceder en el despachador de WPF.

componente Nuestra WPF en cuestión aquí está escrito que hereda de la ventana (es decir. Que no es sólo un mando / control de usuario), y nos muestran el uso de ShowDialog de nuestra lógica de nivel superior que se utiliza para llamar a ShowDialog de la versión de Windows Forms viejos de esta componente. Hay algunos controles WindowsFormsIntegrationHost que hemos utilizado en el interior del componente de WPF para mantener la compatibilidad con algunas de nuestras piezas existentes que no podían ser reescrito en WPF.

He estado investigando esto durante días, pero nunca he encontrado un montón para seguir adelante. Sigo encontrando publicaciones vagamente relacionados que hablar de los mensajes de entrada (ratón y teclado), pero no sé lo que puedo hacer para verificar que; Ya lo he intentado descuartizar el código para eliminar todas las operaciones de ratón / teclado que pude.

Estoy teniendo un tiempo difícil conseguir en cualquier lugar sobre todo porque esta línea de código se aísla por completo (no un padre o hijo de algo que pueda señalar que en realidad viene de nuestro código), y completamente opaca sobre lo que está haciendo.

Esta es una imagen de un gráfico de ANTS llamada de la función ShowDialog que muestra la trayectoria de llamadas para llegar hasta aquí: text alt

Soy plenamente consciente de que esto podría ser algo que sólo tiene que ser hecho como parte de WPF (aunque otros componenets que hemos escrito en WPF no muestran este comportamiento), o que esto es sólo un muy extraño error en ANTS Profiler , pero en este momento necesito para verificar que de una manera u otra. Si alguien me puede decir lo que esté o pueda estar pasando aquí -. O que me señale alguna manera yo sería capaz de averiguarlo yo mismo, voy a dirigir todo tipo de buen karma su camino

ACTUALIZACIÓN: En respuesta a algunas discusión a continuación, aquí es otra vista de las hormigas - éste mejor ilustra la confusión que estoy teniendo (esto es con las hormigas ver en el modo "tiempo de CPU"). He partes de nuestro código apresuradamente censurado, pero ninguna de las funciones relacionadas con el sistema:

text alt

Gracias por mirar!

¿Fue útil?

Solución

He encontrado esto mientras que la búsqueda de información sobre el mismo tema. Voy a añadir lo que sé y ver si ayuda:

Estoy corriendo en una caja de WinXP - el marco WPF está más integrado en Vista y Win7 que en XP. Algo de esto podría ser debido a la forma en WPF corre "por encima" de la mesa de XP, en lugar de dentro de ella.

Me estoy quedando una aplicación WPF nativa pura -. Sin WinForms u otro código

me encontré con esta tratando de determinar por qué simplemente desplazándose una ventana consumiría 100% de la CPU y el tartamudeo mientras lo hace.

Al ejecutar el perfilador de rendimiento AQtime, veo que IntGetMessageW ocupa la mayor parte de ese uso de la CPU al 100%. Esto no se debe a IntGetMessageW la espera de un mensaje, pero algo la función está haciendo realidad.

La única cosa que no he estudiado aún es que tal vez IntGetMessageW nunca ha sido un método rápido, y tal vez simplemente WPF sobreutilización ella. Es posible que los enlaces de datos en WPF utilizan el suministro de mensajes Win32 nativa para actualizar las propiedades de dependencia dentro de WPF. Si ese es el caso, podría ser que mi ventana, simplemente tiene demasiados enlaces.

Otros consejos

Sí, esto es normal. Cualquier aplicación GUI es siempre ejecutar GetMessageW (), a la espera de Windows para enviar un mensaje. No es en realidad quemando ciclos de CPU hacer esto, simplemente bloqueado en un objeto de sincronización interna hasta que se indica algún tipo de evento de interfaz de usuario.

Por supuesto, esto hace que la interfaz de usuario de perfiles de apps de difícil, que realmente necesita unidad de pruebas que ponen a prueba los subcomponentes de su aplicación.

Cuando perfil de una aplicación, es necesario diferenciar entre los tiempo dedicado en un método y ciclos de la CPU consumida. Muchas herramientas de perfilado que el espectáculo tiempo total gastado en un método - que en el caso de algo como GetMessageW va a ser bastante alto. Toda la actividad de la rosca principal de una aplicación de interfaz gráfica de usuario aparecerá a ocurrir dentro de ese método. Eso no es necesariamente un problema, sin embargo ... esto puede ser simplemente la bomba principal de mensaje en espera en un objetos de sincronización y en realidad no consume ciclos.

Yo sugeriría que inicie mediante el uso de la función de muestreo en las hormigas de perfiles para identificar los métodos que se llaman más a menudo y correlacionar aquellos a los métodos que están consumiendo los ciclos de la mayoría de la CPU. una vez que hayas hecho esto, usted decide dónde instrumento de su aplicación a la zambullida en el más allá y tener una idea de lo que los gráficos de llamadas se parecen a los lugares que son más intensivo de la CPU.

usted debe comenzar por la sospecha de su propio código en primer lugar. Es raro que algo así como la infraestructura de WPF o Win32 es responsable de bajo rendimiento o alta de la CPU. Probablemente, el problema se encuentra en algún lugar de su aplicación -. Le ayuda a obtener una sensación general de que los ciclos de CPU se gastan en su programa

Le sugiero que también pasa algún tiempo el aprendizaje de las capacidades del perfilador sea más eficaz. los perfiladores puede ser sofisticado y herramientas hasta que confundir entender qué es lo que están tratando de mostrarle. El tutoral vinculado desde Redgate debe ser un lugar bueno para comenzar, si no lo ha hecho ya. Por ejemplo, la vista Línea de tiempo puede realmente ser un buen punto de partida para ver donde se está produciendo actividad de alto CPU, y confinando su análisis para aquellos segmentos de código ejecutado.

text alt

El gráfico de llamadas es otra herramienta útil en las hormigas, ya que ayuda a perforar en áreas del código que son más caros. La clave es asegurarse de que usted está buscando en el coste global y no sólo el tiempo total .

text alt

Parece que tu suministro de mensajes está bombeando mucho. Podría ser interesante ver qué tipo de mensaje que su cola de mensajes está lleno de. ¿Se puede utilizar Spy ++ en su ventana para ver lo que está pasando?

Editar

He entendido bien el problema.

Hans Passant es correcto, el programa está a la espera de GetMessage por algún evento para el proceso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top