WPF Application Performance improvement Using Freezable Objects

In the Microsoft .net world WPF based applications are still being developed in many organizations. Microsoft had introduced WPF in v 3.0 of .Net framework. Lots of new features and capabilities are being added in it as of v5.0.One such option is Freezable classes. Surprisingly it was introduced in v3.0 of .net framework but still little is known.

When the WPF application size becomes very big the challenges related to runtime performance of the application start surfing up.

There can be multiple ways to improve the application performance. One such option is using Freezable class.

Definition of Freezable

As per Microsoft,

A Freezable object  is a special type of object that has two states: unfrozen and frozen. When unfrozen, a Freezable appears to behave like any other object. When frozen, a Freezable can no longer be modified. So the objects dervied from Freezable based class will have only 2 states either Frozen or Unfrozen.

Freezing a Freezable can improve its performance, because it no longer needs to spend resources on change notifications. A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.

Although the Freezable class has many applications, most Freezable objects in Windows Presentation Foundation (WPF) are related to the graphics sub-system.

If required you can derive classes from Freezable class (namespace: System.Windows, Assembly: WindowsBase.dll). Classes that derive from this class provide detailed change notification, can be made immutable, and can clone themselves.



Some common examples of classes derived from Freezable class are: Brush Pen Geometry Transform AnimationTimelineetc.

How to use

When derived from Freezable based class the objects are normally in Unfrozen (read/write) state.

The objects can be set to Frozen state either from XAML or from code behind. Code behind logic is much earlier to use.

  1. SolidColorBrush brush = newSolidColorBrush(Colors.Green);  
  2. if (brush.CanFreeze)// If Brush is UnFrozen state  
  3. {  
  4.    // Make the brush unmodifiable/ immutable  
  5.    brush.Freeze();  
  6. }  
Now you should not try change any of the property brush Object. Doing so will throw the InvalidOperationException exception.

Another way to set it is from XAML
  1. <SolidColorBrushx: Freeze="True"  
  2. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"/>  
More examples:
  1. Button button = new Button();  
  2. SolidColorBrush brush = new SolidColorBrush(Colors.Blue);  
  3. if (brush.CanFreeze)  
  4. {  
  5.     // Makes the brush unmodifiable.  
  6.     brush.Freeze();  
  7. }  
  8. button.Background = brush;  
  9. if (brush.IsFrozen) // Evaluates to true.  
  10. {  
  11.     // If the brush is frozen, create a clone and modify the clone.  
  12.     SolidColorBrushbrushClone = brush.Clone();  
  13.     brushClone.Color = Colors.Red;  
  14.     button.Background = brushClone;  
  15. }  
  16. else  
  17. {  
  18.     brush.Color = Colors.Yellow; // Change the Property as object is not Frozen  
  19. }  
Another example:
  1. BitmapImage image = new BitmapImage(new Uri("ABC.jpg”,UriKind.RelativeOrAbsolute));  
  2. var image2 = new Image();  
  3. Image2.Source = image;   
  4. grid.Children.Add(image2);  
  5. this code looks absolute fine. However this code is potential source of memory leak due to statement grid.Children.Add(image);  
  6. Rewrite of this code would be:  
  7.   
  8. BitmapImage image = new BitmapImage(new Uri("ABC.jpg”,UriKind.RelativeOrAbsolute));  
  9. var image2 = new Image();  
  10. Image2.Source = image;   
  11. If (image.CanFreeze)  
  12. {  
  13.    image.Freeze();// this will save the memory leak.  
  14. }  
  15. grid.Children.Add(image2);  
If you are willing to create your own class inherited from Freezable class, you need to take care of few things.

 

Next Recommended Reading Freezable Objects in WPF