Optymalizacja wydajności: układ i projekt

Projekt aplikacji WPF może mieć wpływ na wydajność, tworząc niepotrzebne obciążenie podczas obliczania układu i weryfikowania odwołań do obiektów. Konstrukcja obiektów, szczególnie w czasie wykonywania, może mieć wpływ na charakterystykę wydajności aplikacji.

Ten temat zawiera zalecenia dotyczące wydajności w tych obszarach.

Układ

Termin "przekazywanie układu" opisuje proces mierzenia i rozmieszczania elementów członkowskich Panelkolekcji obiektów pochodnych dla elementów podrzędnych, a następnie rysowania ich na ekranie. Przekazywanie układu jest procesem intensywnie obciążającym matematycznie — im większa liczba elementów podrzędnych w kolekcji, tym większa liczba wymaganych obliczeń. Na przykład za każdym razem, gdy obiekt podrzędny UIElement w kolekcji zmienia jego położenie, może wyzwolić nowe przekazywanie przez system układu. Ze względu na ścisłą relację między cechami obiektu i zachowaniem układu ważne jest zrozumienie typu zdarzeń, które mogą wywoływać system układu. Aplikacja będzie działać lepiej, zmniejszając jak najwięcej niepotrzebnych wywołań układu.

System układu kończy dwa przebiegi dla każdego elementu członkowskiego podrzędnego w kolekcji: przebiegu miary i przebiegu rozmieszczania. Każdy obiekt podrzędny zapewnia własną zastąpioną implementację Measure metod i Arrange w celu zapewnienia własnego zachowania układu. W najprostszym układzie jest system rekursywny, który prowadzi do rozmiaru, położenia i narysowania elementu na ekranie.

  • Obiekt podrzędny UIElement rozpoczyna proces układu, najpierw mając mierzone podstawowe właściwości.

  • Właściwości obiektu FrameworkElement , które są powiązane z rozmiarem, takim jak Width, Heighti Margin, są oceniane.

  • Panel-specyficzna logika jest stosowana, na przykład Dock właściwość DockPanel, lub Orientation właściwość StackPanel.

  • Zawartość jest rozmieszczana lub umieszczona po zmierzeniu wszystkich obiektów podrzędnych.

  • Kolekcja obiektów podrzędnych jest rysowana na ekranie.

Proces przekazywania układu jest wywoływany ponownie, jeśli wystąpi którakolwiek z następujących akcji:

  • Obiekt podrzędny jest dodawany do kolekcji.

  • Element A LayoutTransform jest stosowany do obiektu podrzędnego.

  • Metoda UpdateLayout jest wywoływana dla obiektu podrzędnego.

  • W przypadku zmiany wartości właściwości zależności oznaczonej metadanymi wpływającymi na miarę lub rozmieszczanie przechodzi.

Korzystanie z najbardziej wydajnego panelu, jeśli jest to możliwe

Złożoność procesu układu jest bezpośrednio oparta na zachowaniu układu używanych Panelelementów pochodnych. Na przykład kontrolka Grid lub StackPanel zapewnia znacznie więcej funkcji niż kontrolka Canvas . Cena tego większego wzrostu funkcjonalności jest większym wzrostem kosztów wydajności. Jeśli jednak nie potrzebujesz funkcji zapewnianych Grid przez kontrolkę, należy użyć mniej kosztownych alternatyw, takich jak Canvas panel niestandardowy lub.

Aby uzyskać więcej informacji, zobacz Panele — omówienie.

Aktualizacja zamiast zastępowania elementu RenderTransform

Możesz zaktualizować element Transform zamiast zastępować go jako wartość RenderTransform właściwości. Dotyczy to szczególnie scenariuszy obejmujących animację. Aktualizując istniejący Transformelement , należy unikać inicjowania niepotrzebnego obliczania układu.

Tworzenie drzewa od góry do dołu

Po dodaniu lub usunięciu węzła z drzewa logicznego unieważnienie właściwości są wywoływane w obiekcie nadrzędnym węzła i wszystkich jego elementach podrzędnych. W związku z tym należy zawsze przestrzegać wzorca konstrukcji od góry, aby uniknąć kosztów niepotrzebnych unieważnień w węzłach, które zostały już zweryfikowane. W poniższej tabeli przedstawiono różnicę w szybkości wykonywania między tworzeniem drzewa od góry do dołu, gdzie drzewo ma głębokość 150 poziomów z pojedynczym TextBlock i DockPanel na każdym poziomie.

Akcja Budynek drzewa (w ms) Render — obejmuje budynek drzewa (w ms)
Od dołu do góry 366 454
Od góry do dołu 11 96

W poniższym przykładzie kodu pokazano, jak utworzyć drzewo w dół.

private void OnBuildTreeTopDown(object sender, RoutedEventArgs e)
{
    TextBlock textBlock = new TextBlock();
    textBlock.Text = "Default";

    DockPanel parentPanel = new DockPanel();
    DockPanel childPanel;

    myCanvas.Children.Add(parentPanel);
    myCanvas.Children.Add(textBlock);

    for (int i = 0; i < 150; i++)
    {
        textBlock = new TextBlock();
        textBlock.Text = "Default";
        parentPanel.Children.Add(textBlock);

        childPanel = new DockPanel();
        parentPanel.Children.Add(childPanel);
        parentPanel = childPanel;
    }
}
Private Sub OnBuildTreeTopDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim textBlock As New TextBlock()
    textBlock.Text = "Default"

    Dim parentPanel As New DockPanel()
    Dim childPanel As DockPanel

    myCanvas.Children.Add(parentPanel)
    myCanvas.Children.Add(textBlock)

    For i As Integer = 0 To 149
        textBlock = New TextBlock()
        textBlock.Text = "Default"
        parentPanel.Children.Add(textBlock)

        childPanel = New DockPanel()
        parentPanel.Children.Add(childPanel)
        parentPanel = childPanel
    Next i
End Sub

Aby uzyskać więcej informacji na temat drzewa logicznego, zobacz Drzewa w WPF.

Zobacz też