Przegląd Obiekty FreezableFreezable Objects Overview

W tym temacie opisano sposób efektywnego używania i tworzenia obiektów Freezable, które udostępniają specjalne funkcje, które mogą pomóc w zwiększeniu wydajności aplikacji.This topic describes how to effectively use and create Freezable objects, which provide special features that can help improve application performance. Przykłady obiektów Freezable obejmują pędzle, pióra, przekształcenia, geometrie i animacje.Examples of freezable objects include brushes, pens, transformations, geometries, and animations.

Co to jest Freezable?What Is a Freezable?

Freezable jest specjalnym typem obiektu, który ma dwa stany: Niezamrożone i zamrożone.A Freezable is a special type of object that has two states: unfrozen and frozen. Gdy nie zamrożono, Freezable wygląda tak jak każdy inny obiekt.When unfrozen, a Freezable appears to behave like any other object. Po zamrożoniu nie można już modyfikować Freezable.When frozen, a Freezable can no longer be modified.

Freezable zawiera zdarzenie Changed, które powiadamia obserwatorów o wszelkich modyfikacjach obiektu.A Freezable provides a Changed event to notify observers of any modifications to the object. Zamrożenie Freezable może zwiększyć jego wydajność, ponieważ nie trzeba już poświęcać zasobów na powiadomienia o zmianach.Freezing a Freezable can improve its performance, because it no longer needs to spend resources on change notifications. Zamrożone Freezable mogą być również współużytkowane przez wątki, podczas gdy nie zamrożone Freezable.A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.

Chociaż Klasa Freezable ma wiele aplikacji, większość Freezable obiektów w Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) jest związana z podsystemem graficznym.Although the Freezable class has many applications, most Freezable objects in Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) are related to the graphics sub-system.

Klasa Freezable ułatwia korzystanie z pewnych obiektów systemu grafiki i pozwala zwiększyć wydajność aplikacji.The Freezable class makes it easier to use certain graphics system objects and can help improve application performance. Przykłady typów, które dziedziczą z Freezable zawierają klasy Brush, Transformi Geometry.Examples of types that inherit from Freezable include the Brush, Transform, and Geometry classes. Ponieważ zawierają one niezarządzane zasoby, system musi monitorować te obiekty do modyfikacji, a następnie aktualizować odpowiednie zasoby niezarządzane w przypadku zmiany oryginalnego obiektu.Because they contain unmanaged resources, the system must monitor these objects for modifications, and then update their corresponding unmanaged resources when there is a change to the original object. Nawet jeśli nie modyfikujesz obiektu systemowego Graphics, system musi nadal spędzać niektóre z zasobów monitorujących obiekt, w przypadku jego zmiany.Even if you don't actually modify a graphics system object, the system must still spend some of its resources monitoring the object, in case you do change it.

Załóżmy na przykład, że tworzysz pędzel SolidColorBrush i użyjesz go do malowania tła przycisku.For example, suppose you create a SolidColorBrush brush and use it to paint the background of a button.

Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myButton.Background = myBrush;  
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
myButton.Background = myBrush

Gdy przycisk jest renderowany, podsystem WPFWPF Graphics używa dostarczonych informacji do malowania grupy pikseli w celu utworzenia wyglądu przycisku.When the button is rendered, the WPFWPF graphics sub-system uses the information you provided to paint a group of pixels to create the appearance of a button. Mimo że używasz pełnego pędzla kolorów do opisywania, w jaki sposób przycisk powinien być namalowany, Pędzel pełnego koloru nie jest w rzeczywistości używany do malowania.Although you used a solid color brush to describe how the button should be painted, your solid color brush doesn't actually do the painting. System grafiki generuje szybkie i niskiego poziomu obiekty dla przycisku i pędzla. są to obiekty, które faktycznie pojawiają się na ekranie.The graphics system generates fast, low-level objects for the button and the brush, and it is those objects that actually appear on the screen.

W przypadku zmodyfikowania pędzla należy ponownie wygenerować te obiekty niskiego poziomu.If you were to modify the brush, those low-level objects would have to be regenerated. Klasa Freezable to co daje pędzlowi możliwość znalezienia odpowiednich, wygenerowanych obiektów niskiego poziomu i zaktualizowania ich w momencie zmiany.The freezable class is what gives a brush the ability to find its corresponding generated, low-level objects and to update them when it changes. Gdy ta możliwość jest włączona, Pędzel jest określany jako "Niezamrożone".When this ability is enabled, the brush is said to be "unfrozen."

Freezable Metoda Freeze umożliwia wyłączenie tej możliwości samoaktualizacji.A freezable's Freeze method enables you to disable this self-updating ability. Możesz użyć tej metody, aby pędzel stał się "zablokowany" lub nie można go modyfikować.You can use this method to make the brush become "frozen," or unmodifiable.

Uwaga

Nie każdy obiekt Freezable można zablokować.Not every Freezable object can be frozen. Aby uniknąć zgłaszania InvalidOperationException, sprawdź wartość właściwości CanFreeze obiektu Freezable, aby ustalić, czy można ją zamrozić przed podjęciem próby jego zablokowania.To avoid throwing an InvalidOperationException, check the value of the Freezable object's CanFreeze property to determine whether it can be frozen before attempting to freeze it.

if (myBrush.CanFreeze)
{
    // Makes the brush unmodifiable.
    myBrush.Freeze();
}
If myBrush.CanFreeze Then
    ' Makes the brush unmodifiable.
    myBrush.Freeze()
End If

Gdy nie musisz już modyfikować Freezable, zamrażanie zapewnia korzyści z wydajności.When you no longer need to modify a freezable, freezing it provides performance benefits. W przypadku zablokowania pędzla w tym przykładzie system grafiki nie musi już monitorować go pod kątem zmian.If you were to freeze the brush in this example, the graphics system would no longer need to monitor it for changes. System grafiki może również wykonywać inne optymalizacje, ponieważ wie, że pędzel nie ulegnie zmianie.The graphics system can also make other optimizations, because it knows the brush won't change.

Uwaga

Dla wygody Obiekty Freezable pozostają Niezamrożone, chyba że zostaną jawnie zablokowane.For convenience, freezable objects remain unfrozen unless you explicitly freeze them.

Korzystanie z obiektów Freezable platformieUsing Freezables

Użycie niezablokowanego Freezable przypomina użycie dowolnego innego typu obiektu.Using an unfrozen freezable is like using any other type of object. W poniższym przykładzie kolor SolidColorBrush został zmieniony z żółtego na czerwony, gdy jest używany do rysowania tła przycisku.In the following example, the color of a SolidColorBrush is changed from yellow to red after it's used to paint the background of a button. System grafiki działa w tle, aby automatycznie zmienić przycisk z żółtego na czerwony, przy następnym odświeżeniu ekranu.The graphics system works behind the scenes to automatically change the button from yellow to red the next time the screen is refreshed.

Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myButton.Background = myBrush;  

// Changes the button's background to red.
myBrush.Color = Colors.Red;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
myButton.Background = myBrush


' Changes the button's background to red.
myBrush.Color = Colors.Red

Zamrażanie elementu FreezableFreezing a Freezable

Aby nie modyfikować Freezable, należy wywołać metodę Freeze.To make a Freezable unmodifiable, you call its Freeze method. Po zablokowaniu obiektu, który zawiera obiekty Freezable, te obiekty również są zamrożone.When you freeze an object that contains freezable objects, those objects are frozen as well. Na przykład jeśli zablokujesz PathGeometry, dane i segmenty, które zawiera, byłyby również zablokowane.For example, if you freeze a PathGeometry, the figures and segments it contains would be frozen too.

Nie można zamrozić elementu Freezable, jeśli którykolwiek z następujących warunków jest spełniony:A Freezable can't be frozen if any of the following are true:

  • Ma właściwości animowane lub powiązane z danymi.It has animated or data bound properties.

  • Ma właściwości ustawione przez zasób dynamiczny.It has properties set by a dynamic resource. (Zobacz zasoby XAML , aby uzyskać więcej informacji na temat zasobów dynamicznych).(See the XAML Resources for more information about dynamic resources.)

  • Zawiera Freezable obiektów podrzędnych, które nie mogą być zamrożone.It contains Freezable sub-objects that can't be frozen.

Jeśli te warunki mają wartość FAŁSZ i nie zamierzasz modyfikować Freezable, należy zamrozić go, aby uzyskać korzyści wynikające z wydajności opisane wcześniej.If these conditions are false, and you don't intend to modify the Freezable, then you should freeze it to gain the performance benefits described earlier.

Po wywołaniu metody Freeze Freezable nie można już jej modyfikować.Once you call a freezable's Freeze method, it can no longer be modified. Próba zmodyfikowania zablokowanego obiektu powoduje zgłoszenie InvalidOperationException.Attempting to modify a frozen object causes an InvalidOperationException to be thrown. Poniższy kod zgłasza wyjątek, ponieważ próbujemy zmodyfikować pędzel po jego zamrożoniu.The following code throws an exception, because we attempt to modify the brush after it's been frozen.


Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);          

if (myBrush.CanFreeze)
{
    // Makes the brush unmodifiable.
    myBrush.Freeze();
}

myButton.Background = myBrush;  

try {

    // Throws an InvalidOperationException, because the brush is frozen.
    myBrush.Color = Colors.Red;
}catch(InvalidOperationException ex)
{
    MessageBox.Show("Invalid operation: " + ex.ToString());
}


Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)

If myBrush.CanFreeze Then
    ' Makes the brush unmodifiable.
    myBrush.Freeze()
End If

myButton.Background = myBrush

Try

    ' Throws an InvalidOperationException, because the brush is frozen.
    myBrush.Color = Colors.Red
Catch ex As InvalidOperationException
    MessageBox.Show("Invalid operation: " & ex.ToString())
End Try

Aby uniknąć zgłaszania tego wyjątku, można użyć metody IsFrozen, aby określić, czy Freezable jest zamrożona.To avoid throwing this exception, you can use the IsFrozen method to determine whether a Freezable is frozen.


Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);

if (myBrush.CanFreeze)
{
    // Makes the brush unmodifiable.
    myBrush.Freeze();
}            

myButton.Background = myBrush;

if (myBrush.IsFrozen) // Evaluates to true.
{
    // If the brush is frozen, create a clone and
    // modify the clone.
    SolidColorBrush myBrushClone = myBrush.Clone();
    myBrushClone.Color = Colors.Red;
    myButton.Background = myBrushClone;
}
else
{
    // If the brush is not frozen,
    // it can be modified directly.
    myBrush.Color = Colors.Red;
}


Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)

If myBrush.CanFreeze Then
    ' Makes the brush unmodifiable.
    myBrush.Freeze()
End If

myButton.Background = myBrush


If myBrush.IsFrozen Then ' Evaluates to true.
    ' If the brush is frozen, create a clone and
    ' modify the clone.
    Dim myBrushClone As SolidColorBrush = myBrush.Clone()
    myBrushClone.Color = Colors.Red
    myButton.Background = myBrushClone
Else
    ' If the brush is not frozen,
    ' it can be modified directly.
    myBrush.Color = Colors.Red
End If


W poprzednim przykładzie kodu, modyfikowalna kopia została wykonana z zamrożonego obiektu za pomocą metody Clone.In the preceding code example, a modifiable copy was made of a frozen object using the Clone method. W następnej sekcji omówiono klonowanie bardziej szczegółowo.The next section discusses cloning in more detail.

Uwaga

Ponieważ zamrożony Freezable nie może być animowany, system animacji automatycznie tworzy modyfikowalne klony zamrożonych obiektów Freezable podczas próby animowania ich przy użyciu Storyboard.Because a frozen freezable cannot be animated, the animation system will automatically create modifiable clones of frozen Freezable objects when you try to animate them with a Storyboard. Aby wyeliminować narzuty wydajności wynikające z klonowania, pozostaw obiekt niezamrożony, jeśli zamierzasz go animować.To eliminate the performance overhead caused by cloning, leave an object unfrozen if you intend to animate it. Aby uzyskać więcej informacji na temat animacji przy użyciu scenorysów, zobacz Omówienie scenorysów.For more information about animating with storyboards, see the Storyboards Overview.

Zamrażanie z adjustacjiFreezing from Markup

Aby zablokować obiekt Freezable zadeklarowany w znacznikach, należy użyć atrybutu PresentationOptions:Freeze.To freeze a Freezable object declared in markup, you use the PresentationOptions:Freeze attribute. W poniższym przykładzie SolidColorBrush jest zadeklarowana jako zasób strony i zamrożona.In the following example, a SolidColorBrush is declared as a page resource and frozen. Jest on następnie używany do ustawiania tła przycisku.It is then used to set the background of a button.

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="PresentationOptions">

  <Page.Resources>

    <!-- This resource is frozen. -->
    <SolidColorBrush 
      x:Key="MyBrush"
      PresentationOptions:Freeze="True" 
      Color="Red" />
  </Page.Resources>


  <StackPanel>

    <Button Content="A Button" 
      Background="{StaticResource MyBrush}">
    </Button>

  </StackPanel>
</Page>

Aby użyć atrybutu Freeze, należy zmapować do obszaru nazw opcji prezentacji: http://schemas.microsoft.com/winfx/2006/xaml/presentation/options.To use the Freeze attribute, you must map to the presentation options namespace: http://schemas.microsoft.com/winfx/2006/xaml/presentation/options. PresentationOptions jest zalecanym prefiksem do mapowania tej przestrzeni nazw:PresentationOptions is the recommended prefix for mapping this namespace:

xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"

Ponieważ nie wszyscy czytelnicy XAML rozpoznają ten atrybut, zaleca się użycie atrybutu MC: , który można zignorować, aby oznaczyć atrybut Presentation:Freeze jako ignorowany:Because not all XAML readers recognize this attribute, it's recommended that you use the mc:Ignorable Attribute to mark the Presentation:Freeze attribute as ignorable:

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions"

Aby uzyskać więcej informacji, zobacz stronę z atrybutem MC: ignorowany .For more information, see the mc:Ignorable Attribute page.

"Odmrożenie" a Freezable"Unfreezing" a Freezable

Po zamrożoniu Freezable nie może być modyfikowany ani niezamrożony; można jednak utworzyć niezablokowany klon przy użyciu metody Clone lub CloneCurrentValue.Once frozen, a Freezable can never be modified or unfrozen; however, you can create an unfrozen clone using the Clone or CloneCurrentValue method.

W poniższym przykładzie tło przycisku jest ustawione przy użyciu pędzla, a następnie Pędzel jest zablokowany.In the following example, the button's background is set with a brush and that brush is then frozen. Niezablokowana kopia pędzla przy użyciu metody Clone.An unfrozen copy is made of the brush using the Clone method. Klon jest modyfikowany i używany do zmiany tła przycisku z żółtego na czerwony.The clone is modified and used to change the button's background from yellow to red.

Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);

// Freezing a Freezable before it provides
// performance improvements if you don't
// intend on modifying it. 
if (myBrush.CanFreeze)
{
    // Makes the brush unmodifiable.
    myBrush.Freeze();
}

myButton.Background = myBrush;  

// If you need to modify a frozen brush,
// the Clone method can be used to
// create a modifiable copy.
SolidColorBrush myBrushClone = myBrush.Clone();

// Changing myBrushClone does not change
// the color of myButton, because its
// background is still set by myBrush.
myBrushClone.Color = Colors.Red;

// Replacing myBrush with myBrushClone
// makes the button change to red.
myButton.Background = myBrushClone;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)

' Freezing a Freezable before it provides
' performance improvements if you don't
' intend on modifying it. 
If myBrush.CanFreeze Then
    ' Makes the brush unmodifiable.
    myBrush.Freeze()
End If


myButton.Background = myBrush

' If you need to modify a frozen brush,
' the Clone method can be used to
' create a modifiable copy.
Dim myBrushClone As SolidColorBrush = myBrush.Clone()

' Changing myBrushClone does not change
' the color of myButton, because its
' background is still set by myBrush.
myBrushClone.Color = Colors.Red

' Replacing myBrush with myBrushClone
' makes the button change to red.
myButton.Background = myBrushClone

Uwaga

Niezależnie od używanej metody klonowania animacje nie są nigdy kopiowane do nowego Freezable.Regardless of which clone method you use, animations are never copied to the new Freezable.

Metody Clone i CloneCurrentValue dają głębokie kopie Freezable.The Clone and CloneCurrentValue methods produce deep copies of the freezable. Jeśli Freezable zawiera inne zamrożone Obiekty Freezable, są one również klonowane i modyfikowane.If the freezable contains other frozen freezable objects, they are also cloned and made modifiable. Na przykład w przypadku sklonowania zamrożonego PathGeometry w celu zmodyfikowania go elementy i segmenty, które zawiera, są również kopiowane i modyfikowane.For example, if you clone a frozen PathGeometry to make it modifiable, the figures and segments it contains are also copied and made modifiable.

Tworzenie własnej klasy FreezableCreating Your Own Freezable Class

Klasa, która pochodzi od Freezable, ma następujące funkcje.A class that derives from Freezable gains the following features.

  • Specjalne Stany: tylko do odczytu (zamrożony) i zapisywalny.Special states: a read-only (frozen) and a writable state.

  • Bezpieczeństwo wątków: zamrożone Freezable mogą być współużytkowane przez wątki.Thread safety: a frozen Freezable can be shared across threads.

  • Szczegółowe powiadomienie o zmianie: w przeciwieństwie do innych DependencyObjects, Obiekty Freezable zapewniają powiadomienia o zmianach w przypadku zmiany wartości właściwości podrzędnych.Detailed change notification: Unlike other DependencyObjects, Freezable objects provide change notifications when sub-property values change.

  • Łatwe Klonowanie: Klasa Freezable już wdrożyła kilka metod, które tworzą głębokie klony.Easy cloning: the Freezable class has already implemented several methods that produce deep clones.

Freezable jest typem DependencyObjecti w związku z tym używa systemu właściwości zależności.A Freezable is a type of DependencyObject, and therefore uses the dependency property system. Właściwości klasy nie muszą być właściwościami zależności, ale użycie właściwości zależności spowoduje zmniejszenie ilości kodu, który trzeba napisać, ponieważ Klasa Freezable została zaprojektowana z uwzględnieniem właściwości zależności.Your class properties don't have to be dependency properties, but using dependency properties will reduce the amount of code you have to write, because the Freezable class was designed with dependency properties in mind. Aby uzyskać więcej informacji na temat systemu właściwości zależności, zobacz Omówienie właściwości zależności.For more information about the dependency property system, see the Dependency Properties Overview.

Każda podklasa Freezable musi zastąpić metodę CreateInstanceCore.Every Freezable subclass must override the CreateInstanceCore method. Jeśli Klasa używa właściwości zależności dla wszystkich danych, zostanie zakończona.If your class uses dependency properties for all its data, you're finished.

Jeśli Klasa zawiera elementy członkowskie danych niezależności, należy również zastąpić następujące metody:If your class contains non-dependency property data members, you must also override the following methods:

Należy również przestrzegać następujących reguł dostępu i zapisu do elementów członkowskich danych, które nie są właściwościami zależności:You must also observe the following rules for accessing and writing to data members that are not dependency properties:

  • Na początku dowolnego interfejsu API, który odczytuje elementy członkowskie danych niezależności, wywołaj metodę ReadPreamble.At the beginning of any API that reads non-dependency property data members, call the ReadPreamble method.

  • Na początku dowolnego interfejsu API, który zapisuje elementy członkowskie danych właściwości niezależności, wywołaj metodę WritePreamble.At the beginning of any API that writes non-dependency property data members, call the WritePreamble method. (Po wywołaniu WritePreamble w interfejsie API nie trzeba wykonywać dodatkowego wywołania do ReadPreamble, jeśli odczytasz również elementy członkowskie danych niezależności.)(Once you've called WritePreamble in an API, you don't need to make an additional call to ReadPreamble if you also read non-dependency property data members.)

  • Wywołaj metodę WritePostscript przed wyjściem z metod, które zapisują elementy członkowskie danych właściwości niezależności.Call the WritePostscript method before exiting methods that write to non-dependency property data members.

Jeśli Klasa zawiera elementy członkowskie danych niezależnych, które są DependencyObject obiektów, należy również wywołać metodę OnFreezablePropertyChanged za każdym razem, gdy zmieniasz jedną z wartości, nawet jeśli ustawiasz element członkowski na null.If your class contains non-dependency-property data members that are DependencyObject objects, you must also call the OnFreezablePropertyChanged method each time you change one of their values, even if you're setting the member to null.

Uwaga

Bardzo ważne jest, aby rozpocząć każdą metodę Freezable przesłonięcia wywołania do implementacji podstawowej.It's very important that you begin each Freezable method you override with a call to the base implementation.

Przykład niestandardowej klasy Freezable można znaleźć w przykładowej animacji niestandardowej.For an example of a custom Freezable class, see the Custom Animation Sample.

Zobacz takżeSee also