2011-03-23 10 views
37

En el caso de que una pantalla de una aplicación WPF contenga muchos controles primitivos, su renderizado se vuelve lento. ¿Cuáles son las formas recomendadas de mejorar la capacidad de respuesta de una aplicación WPF en tal caso, además de agregar menos controles y usar una tarjeta de video más potente?Formas de mejorar la velocidad de representación de la interfaz de usuario WPF

¿Hay alguna manera de usar de alguna manera el almacenamiento en búfer fuera de la pantalla o algo así?

+0

¿Puedes dar algunos números? Número de controles por ventana, etc. – NVM

+0

@NVM Prácticamente, ahora se trata de unos mil controles personalizados por ventana (el control personalizado consta de varios bordes, bloques de texto y tiene aproximadamente un par de docenas de propiedades de dependencia). La cantidad de controles puede crecer. Pero ya esta cantidad lleva algunos incómodos segundos para visualizarse en la renderización inicial. Además, no proporciona un agradable desplazamiento suave cuando se aumenta el zoom. – rem

+0

Me resulta difícil visualizar una IU con miles de cuadros de texto, todo al mismo tiempo frente al usuario. De todos modos, dependiendo de cómo esté todo arreglado, puede usar uno de los paneles de virtualización incorporados o escribir uno personalizado que solo creará los controles que son visibles. Eso debería acelerar las cosas de manera significativa. – NVM

Respuesta

43

Nuestro equipo se enfrentó a problemas de rendimiento de representación . En nuestro caso, tenemos alrededor de 400 unidades de transporte y deberíamos representar el gráfico de cada unidad con muchos detalles (etiquetas de texto, marcas especiales, geometrías diferentes, etc.).

En la primera de nuestras implementaciones, dividimos cada gráfico en primitivas y compusimos el gráfico de unidades enteras a través de Enlace. Fue muy triste expirience. La reacción de UI fue extremadamente lenta.

Así que decidimos crear un elemento de interfaz de usuario por cada unidad y renderizar el gráfico con DrawingContext. Aunque esto fue mucho mejor en el aspecto de rendimiento, pasamos cerca de un mes mejorando la representación.

algunos consejos:

  1. caché todo. Pinceles, colores, geometrías, textos formateados, glifos. (Por ejemplo, tenemos dos clases: RenderTools y TextCache. Proceso de representación de direcciones de cada unidad a instancia compartida de ambas clases. Por lo tanto, si dos gráficos tienen el mismo texto, su preparación se ejecuta una sola vez)
  2. Congelar Freezable, si planean usarlo por un largo tiempo. Especialmente geometrías. Las geometrías complejas sin congelar ejecutan HitTest extremadamente lento.
  3. Elija las formas más rápidas de representación de cada primitiva. Por ejemplo, hay aproximadamente 6 formas de representación de texto, pero la más rápida es DrawingContext.DrawGlyphs.
  4. Utilice el generador de perfiles para descubrir los puntos calientes. Por ejemplo, en nuestro proyecto teníamos la memoria caché de geometrías y la aprobamos a demanda. Parecía que no hay mejoras posibles. Pero un día pensamos qué pasaría si renderizamos las geometrías una vez y almacenamos imágenes visuales listas para caché. En nuestro caso, ese enfoque fue aceptable. El gráfico de nuestra unidad tiene solo varios estados. Cuando se cambian los datos del gráfico, reconstruimos DrawingVisual para cada estado y los ponemos en el caché.

Por supuesto, esta forma necesita algunas inversiones, es un trabajo aburrido y aburrido, pero el resultado es increíble.

Por cierto: cuando activamos la opción de almacenamiento en caché de WPF (puede encontrar un enlace en las respuestas), nuestra aplicación se colgó.

+0

Me doy cuenta de que esta publicación es un poco antigua, pero me pregunto qué métodos usaste para almacenar en la memoria caché los pinceles, los colores y otras cosas. Siento que podría evitar un retraso si supiera cómo hacerlo. –

+4

[Aquí] (http://pastebin.com/v83XZLTc) Cargué una versión simplificada de mi objeto RenderTools. Y [aquí] (http://pastebin.com/e8VhuHez) es un ejemplo de uso. Si aún tiene preguntas, no dude en preguntar. –

+0

Muchas gracias. Los echaré un vistazo. –

3

Eche un vistazo a la nueva opción de caché (.NET 4.0). (Ver here.)

+0

no es solo para Silverlight? –

+0

@mark: No, no lo es. Lo he usado en proyectos de WPF. Puede hacer clic en el enlace "Otras versiones" en la página vinculada para ver otros marcos admitidos. – Jens

5

que he tenido el mismo problema con una cuadrícula de datos perf muy personalizada desde hace un año, y mi conclusión es:

hay básicamente nada que puedas hacer de su lado (sin que afecta a usted aplicación, es decir: tener un menor número de controles o usando sólo los estilos por defecto)

El enlace se mencionan por Jens es grande, pero inútil en su caso.

El enlace "Optimizar el rendimiento de la aplicación WPF" proporcionado por NVM es casi igual de inútil en mi experiencia: simplemente apela al sentido común y estoy seguro de que no aprenderá nada extraordinario de la lectura. Excepto una cosa tal vez: Debo decir que este enlace me enseñó a poner todo lo que puedo en el recurso de mi aplicación. Debido a que WPF no reinstala nada que pones en el recurso, simplemente reutiliza el mismo recurso una y otra vez. A fin de poner todo lo que pueda en allí (estilos, pinceles, plantillas, fuentes ...)

todo en todos, simplemente no hay manera de hacer que las cosas van más rápido en WPF con tan solo marcar una opción o apagar una otro. Simplemente puede rezar para que MS vuelva a trabajar en su capa de renderizado en un futuro cercano para optimizarla y, mientras tanto, trate de reducir su necesidad de efectos, controles personalizados, etc.

Cuestiones relacionadas