2011-07-17 11 views
5

Tengo una interfaz de usuario muy compleja con una barra de estado en constante cambio con múltiples tipos de mensajes de estado y una IU con un control de gráfico complejo y un mapa geográfico indicativo cargado.Actualizaciones masivas en la interfaz de usuario compleja

Ahora el contexto de datos de estas regiones pequeñas pero complejas tiene ViewModels igualmente complejos como StatusBarVM, ChartingVM, GeoMapVM, etc ... Implementan INotifyPropertyChanged y ObservableCollections.

Cálculo de mis actualizaciones Veo que tengo alrededor de 5000 elementos de UI (etiquetas, barras de progreso, puntos de datos de gráficos, bgcolorsbrushes, etc.) que están cambiando a una velocidad de 1000 actualizaciones de datos por segundo.

¿Cuál es la mejor manera de lograr esta actualización masiva de datos en una interfaz de usuario de WPF?

¿Es el modelo vinculante de WPF capaz de este tipo de grandes actualizaciones? ¿Si es así, cómo? Porque veo que no es óptimo en mi caso. También estoy usando bgworker (para barras de progreso) y uso DIspatcher BeginInvoke ... pero el punto es que incluso entonces las actualizaciones cuelgan el subproceso de la interfaz de usuario ya que los mensajes del operador se ponen en cola esperando que se terminen.

No puedo implementar la virtualización ya que los estados son en tiempo real y tengo que verlos todos en la interfaz de usuario que tengo delante. No puedo perderlos ni por un segundo (por ejemplo, datos geográficos constantes de satélite) .

Ayúdeme a identificar una herramienta correcta o alguna forma de lograr una interfaz de usuario de WPF compleja pero altamente receptiva. ¿Es Dispatcher.PushFrame()?

Respuesta

4

Con tantas actualizaciones por segundo, obtendrá mensajes de actualización "respaldados" en la cola, que es la razón por la que se están bloqueando las actualizaciones de su trabajador de fondo.

Para resolver esto, necesita reducir el número de eventos de actualización que se lanzan.

que haría uso de un enfoque como este:

En mis ViewModels, reemplace la ejecución normal de INotifyPropertyChanged con una llamada a un objeto único que va a enviar la notificación en nombre de ese objeto.

private void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedNotifier.Notify(this, propertyName, propertyChanged); 
} 

Dónde propertyChanged es la variable elemento de almacenamiento de este objetos controladores de eventos.

El método Notify sería algo como esto:

public static void Notify(
    object sender, 
    string propertyName, 
    PropertyChangedEventHandler handlers) 
{ ... } 

Dentro del notificador, no envían el evento inmediatamente - simplemente almacenar el hecho de que tiene que ser enviado.

Si recibe varias notificaciones por el mismo objeto/propiedad, deseche las notificaciones adicionales. Si recibe muchas notificaciones para el mismo objeto pero diferentes propiedades, reemplace la notificación con a single one for all properties.

Ahora, use un temporizador de subprocesos UX para "liberar" las notificaciones cada 50ms más o menos, lo suficientemente rápido para que el usuario no note ninguna diferencia y parezca actualizaciones en tiempo real, pero suficientemente lentas para detectar (y eliminar) notificaciones duplicadas.

+0

esto parece una buena implementación, aunque debo preguntar es las actualizaciones de interfaz de usuario basadas en búfer (seguidas de otras tecnologías de interfaz de usuario tales como ASP.NET, WinForms etc.) lo mismo que ha discutido aquí? –

+1

No estoy seguro, el término "actualizaciones de IU basadas en búfer" no lo reconozco. – Bevan

+1

Debería considerar usar este marco para agrupar las actualizaciones: [Reactive Extensions] (https://rx.codeplex.com/), vea el buffer de la parte con el tiempo. – Thomas

Cuestiones relacionadas