Otimizando o desempenho: Ligação de Dados
Windows Presentation Foundation (WPF) associação de dados fornece uma simples e consistente maneira para aplicações apresentar e interagir com dados. Elementos podem ser vinculados a dados de uma variedade de fontes de dados na forma de objetos CLR e XML.
Este tópico fornece recomendações de desempenho de associação de dados.
Este tópico contém as seguintes seções.
- Como referências de vinculação de dados são resolvidas
- Vinculando a objetos CLR grandes
- Vinculando a um ItemsSource
- Vincular IList a ItemsControl não IEnumerable
- Não converta objetos CLR para XML apenas para vinculação de dados.
- Tópicos relacionados
Como referências de vinculação de dados são resolvidas
Antes de discutir problemas de desempenho de associação de dados, vale a pena explorar como o mecanismo de associação de dados Windows Presentation Foundation (WPF) resolve referências para vinculação de objeto.
A fonte de uma associação de dados Windows Presentation Foundation (WPF) pode ser qualquer objeto CLR. Você pode vincular a propriedades, subpropriedades ou indexadores de um objeto CLR . As referências de vinculação são resolvidas usando reflexão de Microsoft .NET Framework ou um ICustomTypeDescriptor. Aqui estão três métodos para resolver referências para vinculação de objeto.
O primeiro método envolve o uso de reflexão. Nesse caso, o objeto PropertyInfo é usado para descobrir os atributos da propriedade e fornece acesso às propriedades de metadados. Ao usar a interface ICustomTypeDescriptor, o mecanismo de associação de dados usa esta interface para acessar os valores da propriedade. A interface ICustomTypeDescriptor é especialmente útil em casos onde o objeto não tem um conjunto estático de propriedades.
Notificações de alteração de propriedade podem ser fornecidas implementando a interface INotifyPropertyChanged ou usando as notificações de alteração associadas a TypeDescriptor. No entanto, a estratégia preferencial para implementar notificações de alteração de propriedade é usar INotifyPropertyChanged.
Se o objeto de origem for um objeto CLR e a propriedade da fonte é uma propriedade CLR, o mecanismo de associação de dados de Windows Presentation Foundation (WPF) deve primeiro usar reflexão no objeto de origem para obter o TypeDescriptor e em seguida, consultar por um PropertyDescriptor. Essa sequência de operações de reflexão é potencialmente muito demorada de uma perspectiva de desempenho.
O segundo método para resolver referências de objeto envolve um objeto de fonte de CLR que implementa a interface INotifyPropertyChanged e uma propriedade de fonte que é uma propriedade CLR. Nesse caso, o mecanismo de associação de dados usa reflexão diretamente no tipo de fonte e obtém a propriedade necessária. Este é ainda não o melhor método, mas ele custará menos nos conjunto de trabalho de requisitos que o primeiro método.
O terceiro método para resolver referências de objeto envolve um objeto de fonte de DependencyObject e uma propriedade de fonte que é um DependencyProperty e uma propriedade de fonte que é uma propriedade . Nesse caso, o mecanismo de associação de dados não precisa usar reflexão. Em vez disso, o mecanismo de propriedade e o mecanismo de associação de dados juntos resolvem a referência de propriedades de forma independente. Esse é o melhor método para resolver referências de objeto usadas na associação de dados.
A tabela abaixo compara a velocidade da associação de dados da propriedade Text de mil elementos TextBlock usando esses três métodos.
Vinculando a propriedade Text de uma TextBlock |
Tempo de Ligação (ms) |
Tempo de processamento --inclui ligação (ms) |
---|---|---|
A uma propriedade de um objeto CLR. |
115 |
314 |
A uma propriedade de um objeto CLR que implementa INotifyPropertyChanged |
115 |
305 |
Para um DependencyProperty de um DependencyObject. |
90 |
263 |
Vinculando a objetos CLR grandes
Há um impacto significativo no desempenho ao vincular dados a um único objeto CLR com milhares de propriedades. Você pode minimizar esse impacto dividindo o objeto único em vários objetos CLR com menos propriedades. A tabela mostra a vinculação e horários de processamento para associação de dados a um único objeto CLR grande simples versus vários objetos menores.
Vinculação de dados de 1000 Objetos TextBlock |
Tempo de Ligação (ms) |
Tempo de processamento --inclui ligação (ms) |
---|---|---|
Para um objeto CLR com 1000 propriedades. |
950 |
1200 |
Para 1000 objetos CLR com uma propriedade |
115 |
314 |
Vinculando a um ItemsSource
Considere uma situação em que você tenha um objeto CLR List<T> que mantém uma lista de funcionários que você deseja exibir em uma ListBox. Para criar uma correspondência entre esses dois objetos, você deve vincular sua lista de funcionários com a propriedade ItemsSource de ListBox. No entanto, suponha que você tenha um novo funcionário ingressando em seu grupo. Você pode pensar que para inserir essa nova pessoa em seus valores ListBox associados, você iria simplesmente adicionar esta pessoa à sua lista de funcionários e esperar que essa alteração seja reconhecida pelo mecanismo de associação de dados automaticamente. Essa suposição iria se provar falsa; na realidade, a alteração não será refletida em ListBox automaticamente. Isso ocorre porque o objeto CLR List<T> não gera automaticamente um evento de alteração de coleção. Para obter o ListBox para pegar as alterações, você precisará recriar sua lista de funcionários e reanexá-lo para a propriedade ItemsSource de ListBox. Embora essa solução funcione, ela introduz um enorme impacto de performance. Sempre que você reatribuir o ItemsSource ListBox para um novo objeto, o ListBox primeiro joga fora de seus itens anteriores e regenera sua lista inteira. O impacto no desempenho é ampliado se sua ListBox mapeia para um DataTemplate complexo.
Uma solução muito eficiente para esse problema é fazer o funcionário listar um ObservableCollection<T>. Um objeto ObservableCollection<T> gera uma notificação de alteração que o mecanismo de associação de dados pode receber. O evento adiciona ou remove um item de um ItemsControl sem precisar gerar a lista inteira.
A tabela abaixo mostra o tempo necessário para atualizar o ListBox (com virtualização da interface do usuário desativada) quando um item é adicionado. O número na primeira linha representa o tempo decorrido quando o objeto CLR List<T> está vinculado a elementos da ListBox do ItemsSource. O número na segunda linha representa o tempo decorrido quando um ObservableCollection<T> é vinculado aos elementos ListBox de seu ItemsSource. Observe a economia de tempo significativa usando a estratégia de associação de dados ObservableCollection<T>.
Ligação de Dados ao ItemsSource |
Atualizar tempo para 1 item (ms) |
---|---|
Para um objeto CLR List<T> |
1656 |
Para um ObservableCollection<T> |
20 |
Vincular IList a ItemsControl não IEnumerable
Se você tiver uma escolha entre vincular um IList<T> ou um IEnumerable a um objeto ItemsControl, escolha o objeto IList<T>. Vinculando IEnumerable a um ItemsControl Força WPF para criar um objeto invólucro IList<T>, que significa que o seu desempenho é afetado pela sobrecarga desnecessária de um segundo objeto.
Não converta objetos CLR para XML apenas para vinculação de dados.
WPF permite que você faça ligação de dados para conteúdo XML; no entanto, associação de dados para conteúdo XML é mais lento que associação de dados para conteúdo CLR. Não converta dados do objeto CLR para XML se o único objetivo é o de associação de dados.
Consulte também
Conceitos
Optimizing WPF Application Performance
Planejando para desempenho de aplicativos
Otimizando o desempenho: Levando vantagens de hardware
Otimizando o desempenho: Layout and Design
Otimizando o desempenho: 2D Graphics and Imaging
Otimizando o desempenho: Comportamento de objeto
Otimizando o desempenho: Recursos do aplicativo
Otimizando o desempenho: Texto
Otimizando o desempenho: Outras recomendações