2010-07-22 30 views
14

Necesito mostrar muchas filas en una cuadrícula agregada a una frecuencia bastante alta (hasta 10 filas por segundo en algunos casos) Elegí ListView porque supongo que es el control de cuadrícula más rápido en WPF. (Ciertamente mucho más rápido que GridView)WPF: ¿cuál es la forma más eficiente/rápida de agregar elementos a un ListView?

La utilización de la CPU aumenta considerablemente después de que se agregaron cientos de miles de elementos y continúan ingresando. Esto es sorprendente, ya que ListView solo muestra las filas visibles, por lo que no debería importar cómo muchos se agregan en total.

Mi primer enfoque fue vincularlo a ObservableCollection, pero después de un tiempo, la utilización de la CPU aumenta, y toda la ventana se pone nerviosa.

Que intenté vincularlo a una lista normal, que parece ser más rápida, sin embargo, necesito llamar al .Refresh() en la lista a menudo, que después de un tiempo cierra también la CPU.

Que intenté subclassing ObservableCollection insertando trozos esperando que el procesamiento por lotes mejorara el rendimiento/disminuya la carga de trabajo de la CPU, pero este enfoque parece requerir llamar a CollectionView.Refresh que es igual que llamar a Reset() en la colección, y también ineficaz cuando hay muchos artículos en la colección.

Al borrar la agrupación observable y llamar a myListView.Items.Refresh() para volver a ponerlo en 0, devuelve el uso de la CPU al punto de partida.

Comenzando a quedarse sin ideas aquí ... De nuevo, mi objetivo aquí, es agregar muchos elementos y mostrar la cuadrícula de 8 columnas, de la manera más eficiente. ListView parece bueno, solo tiene que haber algunos maneras en que podría pellizcar más que ..

ACTUALIZACIÓN

después del perfilado, ObservableCollection 800k filas de la cuadrícula, la mayor parte del trabajo intensivo de la CPU se realiza por:

  • Sistema (75%). Windows.Media.MediaContext.RenderMessa geHandler (resizedCompositionTarget objeto)
  • (20%) ObservableCollection.OnCollectionChanged (NotifyCoolectionChanged ..)

aunque dependiendo de sesión de esos números varían mucho ..

ACTUALIZACIÓN 2 .. ok BindingList parece ser el claro ganador aquí.

aquí son resultados (en las garrapatas) al lado de 1 millón de filas cada uno (y la adición de 10 artículos por segundo):

ObservableCollection: http://i.imgur.com/7ZoSv.png

BindingList http://i.imgur.com/jm5qF.png

que pueda ver caída global en la actividad de la CPU, y aproximadamente la mitad de los tics necesarios para procesar el árbol en el caso de la lista de encuadernación. Mi agradecimiento a Akash por esta gran idea.

Respuesta

16

En lugar de usar ObservableCollection, sugeriré la clase BindingList, puede hacer algo como esto ..

BindingList<string> list = new BindingList<string>(); 

list.AllowEdit = true; 
list.AllowNew = true; 
list.AllowRemove = true; 

// set the list as items source 
itemCollection.ItemsSource = list; 

// add many items... 

// disable UI updation 
list.RaiseListChangedEvents = false; 

for each(string s in MyCollection){ 
    list.Add(s); 
} 

// after all.. update the UI with following 
list.RaiseListChangedEvents = true; 
list.ResetBindings(); // this forces update of entire list 

Usted puede activar/desactivar la actualización incluso en lotes, en lugar de añadir todo en una sola toma, BindingList ha estado funcionando mejor que ObservableCollection en toda mi interfaz de usuario, me pregunto por qué en todas partes se habla más sobre ObservableCollection cuando BindingList realmente superseds ObservableCollection.

+0

Akash, gracias por esto. Voy a probar esta colección en breve. Una cosa que tengo curiosidad es si hay una manera de hacer inserciones por lotes sin actualizar toda la lista. creo que es una fuente de mucho trabajo de jitter y cpu, cuando se actualizan 800k elementos, etc. –

+0

No creo que actualice 800k elementos, porque los paneles virtualizados solo actualizarán elementos limitados si están en la pantalla. Sin embargo, otra forma sería colocar sus artículos en la página con algún tipo de buscapersonas, en mis aplicaciones, solo cargo 0-20 en primer lugar y dejo que el usuario navegue resto uno por uno, también pueden filtrar usando algún tipo de búsqueda –

+2

ha intentado filtrar ¿tu lista de enlaces? con ObservableCollection, estaba usando CollectionViewSource porque proporciona un filtro, ese filtro se ejecuta en cada elemento agregado. Ese filtro es lo que probablemente se ejecutará en todas las filas después de la actualización. Por lo tanto, tendré que buscar otra forma de agregar el filtrado. –

Cuestiones relacionadas