2010-11-08 12 views
5

En una ventana de WPF, tengo un gráfico de líneas que traza datos en tiempo real (gráfico Quinn-Curtis RealTime para WPF). En resumen, para cada nuevo valor, llamo a un método SetCurrentValue (x, y), y luego al método UpdateDraw() para actualizar el gráfico.Desempeño del despachador de WPF (100-200 actualizaciones/seg)

Los datos vienen a través de una conexión TCP en otro hilo. Cada valor nuevo que entra provoca un evento DataReceived, y su manejador debe trazar el valor en el gráfico y luego actualizarlo. Lógicamente, no puedo llamar a UpdateDraw() directamente, ya que mi gráfico está en el subproceso de UI que no es el mismo subproceso que donde ingresan los datos.

Así que llamo Dispatcher.Invoke (nueva Acción (UpdateDraw ())) - y esto funciona bien, bueno, siempre y cuando actualizo max. 30 veces/seg. Al actualizar con más frecuencia, el Dispatcher no puede mantener el ritmo y el gráfico se actualiza más lentamente de lo que ingresan los datos. Lo probé usando una situación de un solo subproceso con datos simulados y sin el Dispatcher no hay problemas.

Por lo tanto, mi conclusión es que el despachador es demasiado lento para esta situación. De hecho, necesito actualizar 100-200 veces/seg!

¿Hay alguna manera de poner un turbo en el Dispatcher, o hay otras formas de solucionarlo? Cualquier sugerencia es bienvenida.

+1

¿Realmente necesita que la tabla se actualice 100/200 veces por segundo? ¿O simplemente obtienes 100/200 paquetes de datos por segundo? –

+0

Gracias por su sugerencia, pero realmente necesitamos 100 actualizaciones/seg. Vea mi comentario a su publicación a continuación. – KBoek

+2

¿Qué tipo de monitor estás usando? La gran mayoría de los monitores solo se actualizan a 60Hz, por lo que no tiene sentido intentar actualizaciones más rápido que eso. Tan pronto como su tasa de datos entrantes exceda la tasa de fotogramas del monitor, su mejor opción es agrupar los datos entrantes y actualizar la IU una vez por cuadro. –

Respuesta

9

Una opción sería utilizar una cola compartida para comunicar los datos.

Cuando los datos se enciende, que empuja con los datos al final de la cola:

lock (sharedQueue) 
{ 
    sharedQueue.Enqueue(data); 
} 

En el hilo de interfaz de usuario, a encontrar una manera de leer estos datos, por ejemplo, utilizando un temporizador:

var incomingData = new List<DataObject>(); 

lock (sharedQueue) 
{ 
    while (sharedQueue.Count > 0) 
     incomingData.Add(sharedQueue.Dequeue()); 
} 

// Use the data in the incomingData list to plot. 

La idea aquí es que no se está comunicando que los datos que entran en Debido a que tiene un flujo constante de datos, sospecho que no es un problema.. No digo que la implementación exacta como la anterior sea el resto, pero se trata de la idea general.

No estoy seguro de cómo debe verificar los datos nuevos, porque no tengo suficiente información sobre los detalles de la aplicación; pero esto puede ser un comienzo para ti.

+0

Lo siento, pero esa no es una opción. Realmente necesitamos que el gráfico se actualice al menos con 100 actualizaciones/seg. Lo molesto es que esto funciona bien en un solo hilo, así como en Windows Forms (¡con multihilo!) – KBoek

+0

Probé con un enfoque diferente. ¿Esto se ajusta mejor a tu modelo? –

+0

Aunque esta podría no ser la solución que busco, al menos me da una opción. Con el DispatcherTimer, el cuadro se actualizó cada 10 ms. Sin embargo, no me gusta tener un temporizador en mi código cuando no es absolutamente necesario. Ahora estoy pensando en usar WindowsFormsHost y el "viejo" control gráfico de Windows Forms, ya que de alguna manera no se queja de los subprocesos al actualizar. – KBoek

0

El dibujo WPF se produce en una secuencia separada. Dependiendo de la complejidad de su gráfico, su PC debe haber tenido una tarjeta de video de mega-descenso para mantenerse al día con 100 fotogramas por segundo. WPF usa Direct3D para dibujar todo en la pantalla y optimizar el controlador de video para esto se ha agregado a Vista (mejorado en Windows 7). Por lo tanto, en XP puede tener problemas simplemente debido a su alta tasa de salida de datos en un sistema operativo mal diseñado.

A pesar de todo eso, no veo ninguna razón para imprimir información en la pantalla con una tasa de más de 30-60 fotogramas por segundo. ¡Vamos! Incluso los tiradores de FPS no requieren reflejos tan fuertes del jugador. ¿Quieres decirme que tu pobre tabla sí? :) Si a través de este resultado, produces algunos efectos secundarios, que es lo que realmente necesitas, entonces es una historia completamente diferente. Cuéntanos más sobre el problema entonces.

+0

E incluso si de alguna manera administras 100 actualizaciones por segundo, ¡eso no sirve de nada si tu monitor solo se refresca 60 veces por segundo! –

+0

Estoy usando W7 Pro x64, por lo que el rendimiento deficiente no se debe a XP. Si lees un poco sobre Quinn Curtis, descubrirás que tienen estos controles de gráfico en tiempo real, que solo trazan la línea y no necesitan un rediseño completo para cada nuevo valor. Muy conveniente. – KBoek

+0

Como escribí anteriormente, probé esto con éxito con WPF de un solo subproceso y con Windows Forms. Es por eso que mi conclusión es que el problema radica en el despachador. – KBoek

6

Sus requisitos son absurdos: en serio NO necesita 100-200 actualizaciones por segundo, especialmente cuando la pantalla funciona normalmente a 60 actualizaciones por segundo. La gente no los verá de todos modos.

  • Ingrese los datos nuevos en una cola.
  • Dispare un evento de extracción en/para el despachador.
  • datos Santize en la cola (excelentes referencias fuera dobles, últimos triunfos válidos) y los pusieron in.l

30 actualizaciones por segundo son suficientes - la gente no ver una diferencia. Tuve problemas de rendimiento en algunos datos financieros a alta carga con un T & S hasta que lo hice, ahora el gráfico se ve mejor.

Keep Dispatcher mueve tan pocos como puedas.

4

Me gustaría saber por qué desea actualizar un gráfico 200 veces por segundo cuando su monitor ni siquiera puede mostrarlo tan rápido. (Recuerde, los monitores de pantalla plana normales tienen una velocidad de actualización de 60 fps)

¿De qué sirve actualizar algo 200 veces por segundo cuando solo puede ver las actualizaciones 60 veces por segundo? También podría lotear los datos entrantes y actualizar el gráfico a 60 fps ya que de todos modos no podrá ver la diferencia.

Si no se trata sólo acerca mostrando los datos, sino que estás haciendo algo más con ella - dicen que está supervisando a ver si se alcanza un cierto umbral - que recomiendo dividir el sistema en 2 partes: una parte monitoreando a toda velocidad, el otro mostrando de manera independiente a la velocidad máxima que su monitor puede manejar: 60 fps.

Por favor, díganos por qué quiere actualizar un ui-control con más frecuencia de la que se le puede mostrar al usuario.

Cuestiones relacionadas