Ottimizzazione delle prestazioni: associazione dati
L'associazione dati Windows Presentation Foundation (WPF) rappresenta per le applicazioni un modo semplice e coerente di presentare e interagire con i dati. È possibile associare gli elementi a numerose origini dati sotto forma di oggetti CLR e XML.
In questo argomento vengono forniti i requisiti relativi alle prestazioni dell'associazione dati.
Nel presente argomento sono contenute le seguenti sezioni.
- Risoluzione dei riferimenti per l'associazione dati
- Associazione a oggetti CLR di grandi dimensioni
- Associazione a una proprietà ItemsSource
- Associare IList a un oggetto ItemsControl, non IEnumerable
- Non convertire oggetti CLR in XML solo per l'associazione dati.
- Argomenti correlati
Risoluzione dei riferimenti per l'associazione dati
Prima di trattare i problemi di prestazione legati all'associazione dati, è opportuno approfondire come i riferimenti agli oggetti per l'associazione dati vengano risolti dal motore di associazione dati di Windows Presentation Foundation (WPF) .
L'origine di un'associazione dati Windows Presentation Foundation (WPF) può essere qualsiasi oggetto CLR. È possibile stabilire associazioni a proprietà, proprietà secondarie o indici di un oggetto CLR. I riferimenti dell'associazione vengono risolti utilizzando la reflection di Microsoft .NET Framework o un oggetto ICustomTypeDescriptor. Di seguito vengono descritti tre modi per risolvere riferimenti a oggetti per l'associazione.
Il primo metodo richiede l'utilizzo della reflection. In questo caso, l'oggetto PropertyInfo viene utilizzato per individuare gli attributi della proprietà e per accedere ai metadati della proprietà. Quando si utilizza l'interfaccia ICustomTypeDescriptor, il motore di associazione dati utilizza questa interfaccia per accedere ai valori della proprietà. L'interfaccia ICustomTypeDescriptor è particolarmente utile nei casi in cui l'oggetto non dispone di un insieme statico di proprietà.
Le notifiche di modifica delle proprietà possono essere fornite implementando l'interfaccia INotifyPropertyChanged o utilizzando le notifiche di modifica associate all'oggetto TypeDescriptor. La strategia da preferire per l'implementazione delle notifiche di modifica delle proprietà consiste tuttavia nell'utilizzare l'interfaccia INotifyPropertyChanged.
Se l'oggetto di origine è un oggetto CLR e la proprietà di origine è una proprietà CLR, il motore di associazione dati di Windows Presentation Foundation (WPF) deve innanzitutto utilizzare la reflection sull'oggetto di origine per ottenere l'oggetto TypeDescriptor e quindi eseguire una query per un oggetto PropertyDescriptor. Questa sequenza di operazioni di reflection richiede potenzialmente molto tempo da un punto di vista delle prestazioni.
Il secondo metodo di risoluzione dei riferimenti agli oggetti richiede un oggetto di origine CLR che implementa l'interfaccia INotifyPropertyChanged e una proprietà di origine che è una proprietà CLR. In questo caso, il motore di associazione dati utilizza direttamente la reflection sul tipo di origine e ottiene la proprietà necessaria. Sebbene presenti requisiti del working set inferiori rispetto al primo metodo, non si tratta ancora del metodo ottimale.
Il terzo metodo di risoluzione dei riferimenti agli oggetti richiede un oggetto di origine DependencyObject e una proprietà di origine DependencyProperty. In questo caso, non è richiesto l'utilizzo della reflection da parte del motore di associazione dati. Il motore della proprietà e il motore di associazione dati risolvono il riferimento alla proprietà in modo indipendente. Si tratta del metodo ottimale per la risoluzione dei riferimenti agli oggetti utilizzati per l'associazione dati.
Nella tabella riportata di seguito viene confrontata la velocità di associazione dati della proprietà Text di milli elementi TextBlock utilizzando questi tre metodi.
Associazione della proprietà Text di un TextBlock |
Tempo di associazione (ms) |
Tempo di rendering – include l'associazione (ms) |
---|---|---|
A una proprietà di un oggetto CLR |
115 |
314 |
A una proprietà di un oggetto CLR che implementa INotifyPropertyChanged |
115 |
305 |
A una proprietà DependencyProperty di un oggetto DependencyObject. |
90 |
263 |
Associazione a oggetti CLR di grandi dimensioni
Quando si stabilisce un'associazione dati a un singolo oggetto CLR con migliaia di proprietà, l'impatto sulle prestazioni è notevole. È possibile limitare questo impatto dividendo il singolo oggetto in più oggetti CLR con un numero inferiore di proprietà. Nella tabella vengono elencati i tempi di associazione e rendering per l'associazione dati a un singolo oggetto CLR di grandi dimensioni rispetto a più oggetti di dimensioni inferiori.
Associazione dati di 1000 oggetti TextBlock |
Tempo di associazione (ms) |
Tempo di rendering – include l'associazione (ms) |
---|---|---|
A un oggetto CLR con 1000 proprietà |
950 |
1200 |
A 1000 oggetti CLR con una proprietà |
115 |
314 |
Associazione a una proprietà ItemsSource
Si consideri uno scenario in cui un oggetto CLR List<T> contiene un elenco di dipendenti da visualizzare in un controllo ListBox. Per creare una corrispondenza tra questi due oggetti, è necessario associare l'elenco dei dipendenti alla proprietà ItemsSource del controllo ListBox. Si supponga ora che un nuovo dipendente si unisca al gruppo. Si potrebbe pensare che per inserire questo nuovo dipendente nei valori ListBox associati, sia semplicemente necessario aggiungerlo all'elenco dei dipendenti e attendere che tale modifica venga riconosciuta automaticamente dal motore di associazione dati. Tale ipotesi finirebbe per rivelarsi falsa; in realtà, la modifica non verrà riflessa automaticamente nel controllo ListBox. L'oggetto CLRList<T>, infatti, non genera automaticamente un evento di modifica dell'insieme. Affinché l'oggetto ListBox rilevi automaticamente le modifiche, è necessario ricreare l'elenco dei dipendenti e collegarlo nuovamente alla proprietà ItemsSource del controllo ListBox. Questa soluzione funziona, ma produce un notevole impatto sulle prestazioni. Ogni volta che la proprietà ItemsSource del controllo ListBox viene riassegnata a un nuovo oggetto, il controllo ListBox elimina gli elementi precedenti e rigenera l'intero elenco. L'impatto sulle prestazioni risulta maggiore se il controllo ListBox viene mappato a un oggetto DataTemplate complesso.
Una soluzione molto efficace a questo problema consiste nell'impostare l'elenco dei dipendenti come ObservableCollection<T>. Un oggetto ObservableCollection<T> genera una notifica di modifica che il motore di associazione dati può ricevere. L'evento aggiunge o rimuove un elemento da ItemsControl senza la necessità che l'intero elenco venga rigenerato.
Nella tabella riportata di seguito è indicato il tempo necessario per l'aggiornamento del controllo ListBox (con la virtualizzazione dell'interfaccia utente disattivata) quando viene aggiunto un elemento. Il numero nella prima riga rappresenta il tempo trascorso quando l'oggetto CLRList<T> viene associato alla proprietà ItemsSourcedell'elemento ListBox. Il numero nella seconda riga rappresenta il tempo trascorso quando un oggetto ObservableCollection<T> viene associato alla proprietà ItemsSource dell'elemento ListBox. Si noti il notevole risparmio di tempo se si utilizza la strategia di associazione dati dell'oggetto ObservableCollection<T>.
Associazione dati della proprietà ItemsSource |
Tempo di aggiornamento per 1 elemento (ms) |
---|---|
A un oggetto CLR List<T> |
1656 |
A un oggetto ObservableCollection<T> |
20 |
Associare IList a un oggetto ItemsControl, non IEnumerable
Se è possibile scegliere tra l'associazione di un oggetto IList<T> o di un oggetto IEnumerable a un oggetto ItemsControl, scegliere IList<T>. L'associazione di IEnumerable a ItemsControl impone in WPF la creazione di un oggetto IList<T> wrapper, con conseguente calo delle prestazioni dovuto al sovraccarico non necessario di un secondo oggetto.
Non convertire oggetti CLR in XML solo per l'associazione dati.
WPF consente di eseguire l'associazione dati a contenuto XML. L'associazione dati a contenuto XML è tuttavia più lenta rispetto all'associazione dati a oggetti CLR. Non convertire dati di oggetti CLR a XML se l'unico scopo è l'associazione dati.
Vedere anche
Attività
Procedura dettagliata: memorizzazione dei dati di un'applicazione nella cache di un'applicazione WPF
Concetti
Ottimizzazione delle prestazioni di applicazioni WPF
Pianificazione delle prestazioni dell'applicazione
Ottimizzazione delle prestazioni: sfruttare appieno l'hardware
Ottimizzazione delle prestazioni: layout e progettazione
Ottimizzazione delle prestazioni: grafica bidimensionale e creazione di immagini
Ottimizzazione delle prestazioni: comportamento degli oggetti
Ottimizzazione delle prestazioni: risorse di applicazioni
Ottimizzazione delle prestazioni: testo