2010-11-24 20 views
7

Tengo una aplicación WPF (.NET 4) que tiene una ventana principal, y dentro de esa ventana principal muestra muchos UserControls más pequeños. Varias acciones realizadas por el usuario causan el UserControls que se muestran para ser reemplazadas por otros controles diferentes con datos diferentes.Problemas de rendimiento de WPF InitializeComponent

Sin embargo, estoy teniendo problemas de rendimiento al cambiar estos controles. El subproceso de despachador de WPF va al 100% de la CPU al cargar los controles. En máquinas más antiguas, o con un mayor número de controles, ¡esto puede hacer que la aplicación parezca bloquearse por hasta 30 segundos!

perfiles indica que casi todo este tiempo de CPU se dedica a llamar a los diversos InitializeComponent métodos de todos los diferentes UserControls - nadie de control parece ser mucho peor que cualquier otro, todos ellos parecen tener entre 0,2 y 0,5 segundos (en mi máquina de desarrollo con un procesador rápido y una buena tarjeta gráfica).

Por lo que sé, InitializeComponent es donde WPF realmente carga el xaml compilado en la memoria.

No sé qué hacer aquí. Me gustaría preinicializar cosas en un hilo de fondo, pero todos los controles de WPF deben ser creados y utilizados en el hilo del despachador, por lo que no creo que esto sea posible.

De lo contrario, parece que las únicas opciones que tengo son eliminar todo mi xaml ??

Cualquier ayuda sería muy apreciada

+1

sin saber más sobre tu aplicación (detalles específicos + código), solo puedo imaginar que tienes una gran cantidad de controles de usuario (+50) y/o enlaces de datos muy pesados. Entonces, la única respuesta sería rediseñar la lógica de su aplicación. Lo que también debes entender es que WPF es absolutamente una mierda cuando se trata de una gran cantidad de controles/datos, porque está muy desoptimizado (supongo que es un nivel demasiado alto de un framework). Tal vez pruebe WinForms para su aplicación (que es un poco mejor) o escriba todo en C++/directx nativo (a'la Photoshop, estilo AutoCAD) – Marko

+0

http://jeremiahmorrill.wordpress.com/2011/02/14/a-critical -deep-dive-into-the-wpf-rendering-system/- Supongo que los controles se están cargando, el renderizado generado y quizás en caché. Menciona PIX (una herramienta de perfilado WPF) que te gustaría probar. – gbjbaanb

Respuesta

0

El método InitializeComponent lleva tiempo porque tiene que insertar el control en el árbol/Lógico visual y asegurar a todos los atascamientos, temas, etc. recursos previstos

Mi única sugerencia es - ¿es posible inicializar todos los controles potenciales desde el principio, y luego mostrarlos/ocultarlos cuando sea necesario usando la propiedad Visibility?

Puede usar Freezable para el almacenamiento en caché de alguna IU, pero si son controles de usuario, lo más probable es que desee que su usuario interactúe con ellos.

+0

Gracias por la respuesta, pero inicialmente habíamos cargado todos los controles por adelantado y solo mostramos los que necesitamos. Luego hubo un retraso enorme (más de un minuto en las máquinas más lentas) cuando se mostró por primera vez el formulario, lo que fue una experiencia de usuario aún peor que el comportamiento actual :-( –

2

Para revisar esto, tenemos muchos controles complejos en la pantalla, ¡pero no podemos deshacernos de ellos para mantener a WPF feliz!

más experimentación con perfiles mostraron que el uso de controles personalizados (básicamente sólo una clase C# directamente derivadas de Control y la definición de la interfaz de usuario en un Generic.xaml temas único archivo parece incurrir en el éxito de la carga y analizar el XAML vez. A partir de entonces, cada control Sólo se aplica la preexistente tema.

los controles personalizados son mucho más difíciles de trabajar que UserControls, pero esto no parece ayudar a nuestro rendimiento de carga mucho.

0

para el registro, que tenía una ventana con una el tiempo de carga alrededor de 1500 ~ 2000 ms, el problema fue el iconos.

que estaba usando una herramienta para la conversión de SVG a elementos XAML DrawingImage, y un control de usuario con un diccionario de recursos grande con una imagen de dibujo para cada icono utilizado

El InitializeComponent era tan lento, ya que tuvo que analizar esa gran Archivo XAML que contiene todos los datos vectoriales para las imágenes

Espero que ayude.

Cuestiones relacionadas