Aracılığıyla paylaş


Performansı İyi hale getirme: Veri Bağlama

Windows Presentation Foundation (WPF) veri bağlama, uygulamaların veri sunup verilerle etkileşim kurması için basit ve tutarlı bir yol sağlar. Öğeler, çeşitli veri kaynaklarından alınan verilere CLR nesneler ve XML biçiminde bağlanabilir.

Bu konu, veri bağlama performansı önerileri sağlar.

Veri Bağlama Referansları Nasıl Çözülür?

Veri bağlama performansı sorunlarını ele almadan önce, Windows Presentation Foundation (WPF) veri bağlama altyapısının bağlama için nesne başvurularını nasıl çözümlediğinden bahsedebilirsiniz.

Windows Presentation Foundation (WPF) veri bağlamasının kaynağı herhangi bir CLR nesnesi olabilir. bir CLR nesnesinin özelliklerine, alt özelliklerine veya dizin oluşturucularına bağlanabilirsiniz. Bağlayıcı referanslar, Microsoft .NET Framework refleksiyonu veya bir ICustomTypeDescriptorkullanılarak çözülür. Bağlama için nesne başvurularını çözümlemeye yönelik üç yöntem aşağıdadır.

İlk yöntem yansımayı kullanmayı içerir. Bu durumda, PropertyInfo nesnesi özelliğin özniteliklerini bulmak için kullanılır ve özellik meta verilerine erişim sağlar. ICustomTypeDescriptor arabirimini kullanırken, veri bağlama altyapısı özellik değerlerine erişmek için bu arabirimi kullanır. ICustomTypeDescriptor arabirimi özellikle nesnenin statik bir özellik kümesine sahip olmadığı durumlarda kullanışlıdır.

Özellik değişikliği bildirimleri, INotifyPropertyChanged arabirimi uygulanarak veya TypeDescriptorile ilişkili değişiklik bildirimleri kullanılarak sağlanabilir. Ancak, özellik değişikliği bildirimlerini uygulamak için tercih edilen strateji INotifyPropertyChangedkullanmaktır.

Kaynak nesne CLR bir nesneyse ve kaynak özelliği bir CLR özelliğiyse, Windows Presentation Foundation (WPF) veri bağlama altyapısının ilk olarak TypeDescriptoralmak için kaynak nesnedeki yansımayı kullanması ve ardından bir PropertyDescriptorsorgulaması gerekir. Bu yansıma işlemleri dizisi, performans açısından çok zaman alabilir.

Nesne başvurularını çözümlemek için ikinci yöntem, CLR arabirimini uygulayan bir INotifyPropertyChanged kaynak nesnesi ve CLR özelliği olan bir kaynak özelliği içerir. Bu durumda, veri bağlama altyapısı doğrudan kaynak türü üzerinde yansıma kullanır ve gerekli özelliği alır. Bu hala en uygun yöntem değildir, ancak çalışma kümesi gereksinimlerinde ilk yöntemden daha düşük maliyetlidir.

Nesne başvurularını çözümlemek için üçüncü yöntem, DependencyObject olan bir kaynak nesneyi ve DependencyPropertyolan bir kaynak özelliği içerir. Bu durumda, veri bağlama altyapısının yansıma kullanması gerekmez. Bunun yerine, özellik altyapısı ve veri bağlama altyapısı birlikte özellik başvuruyu bağımsız olarak çözümler. Bu, veri bağlama için kullanılan nesne başvurularını çözümlemek için en uygun yöntemdir.

Aşağıdaki tablo, bu üç yöntemi kullanarak bin Text öğesinin TextBlock özelliğini bağlayan verilerin hızını karşılaştırır.

Bir TextBlock'un Text özelliğini bağlama Bağlama zamanı (ms) İşleme süresi -- bağlama süresini içerir (ms)
CLR nesnesinin özelliğine 115 314
CLR uygulayan bir INotifyPropertyChanged nesnesinin özelliğine 115 Üç yüz beş
DependencyProperty'nin bir DependencyObject'su. 90 263

Büyük CLR Nesnelerine Bağlama

Binlerce özelliğe sahip tek bir CLR nesnesine veri bağladığınızda önemli bir performans etkisi olur. Tek nesneyi daha az özelliğe sahip birden çok CLR nesnesine bölerek bu etkiyi en aza indirebilirsiniz. Tabloda, tek bir büyük CLR nesnesine karşılık birden çok küçük nesne için veri bağlama ve render süreleri gösterilmektedir.

1000 TextBlock nesnesinin veri bağlaması Bağlama zamanı (ms) İşleme süresi -- bağlama süresini içerir (ms)
1000 özelliği olan bir CLR nesnesine 950 1200
Bir özelliği olan 1000 CLR nesneye 115 314

ItemsSource'a Bağlantı Kurma

Bir senaryo düşünün ki, çalışanların listesini içeren bir CLRList<T> nesnesine sahipsiniz ve bu listeyi bir ListBoxiçinde görüntülemek istiyorsunuz. Bu iki nesne arasında bir yazışma oluşturmak için, çalışan listenizi ItemsSourceListBox özelliğine bağlarsınız. Ancak, grubunuzla birlikte yeni bir çalışanınız olduğunu varsayalım. Bu yeni kişiyi ilişkili ListBox değerlerinize eklemek için, bu kişiyi çalışan listenize eklemeniz ve bu değişikliğin veri bağlama altyapısı tarafından otomatik olarak tanınmasını beklemeniz gerektiğini düşünebilirsiniz. Bu varsayım yanlış olduğu ortaya çıkar; aslında, değişiklik ListBox'a otomatik olarak yansıtılmayacaktır. Bunun nedeni, CLRList<T> nesnesinin bir koleksiyonun değiştirildiği olayı otomatik olarak tetiklememesidir. Değişikliklerin ListBox üzerinde uygulanabilmesi için, çalışan listenizi tekrar oluşturmanız ve onu ItemsSource’nin ListBox özelliğine yeniden eklemeniz gerekir. Bu çözüm işe yarasa da, büyük bir performans etkisine neden olur. ItemsSource ListBox yeni bir nesneye her yeniden atadığınızda, ListBox önce önceki öğelerini atar ve listenin tamamını yeniden oluşturur. ListBox, karmaşık bir DataTemplateile eşlenirse performans üzerindeki etki artar.

Bu sorunun çok verimli bir çözümü, çalışan listenizi ObservableCollection<T>yapmaktır. ObservableCollection<T> nesnesi, veri bağlama altyapısının alabileceği bir değişiklik bildirimi oluşturur. Bir olay, ItemsControl'dan bir öğe ekler veya çıkarır ve bunu yaparken listenin tamamını yeniden oluşturmak gerekmez.

Aşağıdaki tabloda, bir öğe eklendiğinde ListBox (ui sanallaştırma kapalıyken) güncelleştirilmesi için geçen süre gösterilmektedir. İlk satırdaki sayı, CLRList<T> nesnesinin ListBox öğenin ItemsSourcebağlı olduğu geçen süreyi temsil eder. İkinci satırdaki sayı, bir ObservableCollection<T>ListBox öğesinin ItemsSourcebağlı olduğunda geçen süreyi temsil eder. ObservableCollection<T> veri bağlama stratejisini kullanarak önemli ölçüde zaman tasarrufu elde edin.

Verileri ItemsSource Bağlama 1 öğenin güncelleme süresi (ms)
CLR List<T> nesnesine 1656
Bir ObservableCollection<T>'ye 20

IList'i ItemsControl'e Bağlayın, IEnumerable Değil

bir IList<T> veya IEnumerable bir ItemsControl nesnesine bağlama arasında bir seçeneğiniz varsa, IList<T> nesnesini seçin. IEnumerable'ı bir ItemsControl'e bağlamak, WPF'yi bir IList<T> sarmalayıcı nesnesi oluşturmaya zorlar; bu, performansınızın ikinci bir nesnenin neden olduğu gereksiz yük nedeniyle olumsuz etkilendiği anlamına gelir.

CLR nesnelerini Yalnızca Veri Bağlama için XML'ye dönüştürmeyin.

WPF, XML içeriğine veri bağlamanızı sağlar; ancak XML içeriğine veri bağlama, CLR nesnelere veri bağlamadan daha yavaştır. Tek amaç veri bağlamaysa CLR nesne verilerini XML'ye dönüştürmeyin.

Ayrıca bakınız