Okkio a questo scenario:
var subjects = new EntityCollection<Subject>();
var dataView = subjects.DefaultView;

subjects.Add( new Person() );
Adesso immaginate che dataView sia in binding con una ListView, dataView è IBindingListView e questo fa si che la ListView sia in grado di reagire alle variazioni che subisce dataView, ecco che il codice di cui sopra fa “magicamente apparire” nella ListView un nuovo item.
Adesso fate questa cosa:
var subjects = new EntityCollection<Subject>();
var dataView = subjects.DefaultView;

for( var i = 0; i < 1000; i++ )
{
    subjects.Add( new Person() );
}
La stessa cosa, ma un po’ di volte in fila… ecco ci mette una vita, ma veramente una vita :-). Il tutto semplicemente perchè ad ogni variazione la ListView deve reagire, capire cosa è successo e mettere in piedi tutto il giro del fumo per far comparire il nuovo elemento, un sacco di lavoro.
Rispetto e conoscenza
In uno scenario come quello di prima, tipico del caricamento massivo di dati a seguito di una query, è importante trattare bene il motore di binding, ad esempio così:
var subjects = new EntityCollection<Subject>();
var dataView = subjects.DefaultView;

subjects.BeginInit();
for( var i = 0; i < 1000; i++ )
{
    subjects.Add( new Person() );
}
subjects.EndInit( true );
che altro non fa che sospendere la generazione degli eventi, che stimolano il binding, fino a nuovo ordine. E il processo torna ad essere una scheggia.
.m