بهبود کارایی برنامه WPF با استفاده از شیء های Freezable

در این مقاله می آموزیم که چطور می توانیم در یک برنامه ی WPF با استفاده از شیء های Freezable (شیء هایی که قابلیت Freez شدن دارند.) راندمان و کارایی برنامه را افزایش بدهیم.

بهبود کارایی برنامه WPF با استفاده از شیء های Freezable

در دنیای Microsoft .net ، بسیاری از سازمان ها در حال توسعه ی برنامه های مورد نیازشان در قالب برنامه های WPFهستند. شرکت Microsoft تکنولوژی WPF را در نسخه ی 3.0 از .Net framework معرفی کرد. بسیاری از قابلیت ها و ویژگی های دیگر نیز در نسخه ی 5.0 این برنامه به آن اضافه شده اند. یکی از این ویژگی ها ، کلاس های Freezable است. البته این کلاس ها در نسخه 3.0 مجموعه .Net framework نیز وجود داشتند ولی در نسخه ی 5.0 به صورت گسترده ای مورد توجه و استفاده قرار گرفتند.

زمانی که  سایز یک برنامه WPF بسیار بزرگ می شود، چالش های مربوط به کارایی در زمان اجرای برنامه ظاهر می شوند.

راه های متعددی برای بهبود کارایی برنامه ها وجود دارد که یکی از آن ها استفاده از کلاس های Freezable است.

مفهوم Freezable

Microsoft در این باره اینطور می گوید:

یک شیء Freezable یک نوع خاص از شیء است که دارای دو حالت است : unfrozen و frozen . وقتی در حالت unfrozen است، مانند شیء های دیگر عمل می کند. وقتی در حالت frozen است، قابلیت ویرایش غیر فعال می شود. بنابراین شیء هایی که از کلاس های Freezable مشتق می شوند، فقط دارای دو حالت هستند.

قرار دادن یک شیء Freezable در حالت Freezing می تواند باعث بهبود عملکرد آن شود، زیرا این شیء دیگر نیازی به منابع برای اطلاع رسانی های مربوط به ویرایش و تغییر ندارد. اگر یک Freezable در حالت frozen باشد، می تواند در میان thread ها به اشتراک گذاشته شود، در حالی که یک Freezable در حالت unfrozen این قابلیت را ندارد.

اگر چه یک کلاس Freezable کاربرد های زیادی دارد، اما اکثر شیء های Freezable در Windows Presentation Foundation (WPF) مربوط به graphics sub-system می باشند.

در صورت نیاز شما می توانید کلاس هایی داشته باشید که از کلاس Freezable ارث بری کنند.( namespace: System.Windows, Assembly: WindowsBase.dll) . کلاس هایی که از این کلاس مشتق می شوند، امکان تغییرات جزئی را به کاربر می دهند، ولی شما می توانید آن ها را به حالت غیرقابل ویرایش نیز دربیاورید.

برخی از مثال های متداول کلاس های مشتق شده از کلاس های Freezable عبارتند از : Brush Pen Geometry Transform AnimationTimelineetc .

نحوه ی استفاده

زمانی که یک کلاس از کلاس های Freezable ارث بری می کند، به صورت معمول در حالت Unfrozen (read/write) قرار دارد.

شیء ها می توانند هم از طریق XAML و هم از طریق code behind به حالت Frozen بروند. استفاده از Code behind یک روش قدیمی است که در گدشته نیز از آن بسیار استفاده می شده است.


    SolidColorBrush brush = newSolidColorBrush(Colors.Green);  
    if (brush.CanFreeze)// If Brush is UnFrozen state  
    {  
       // Make the brush unmodifiable/ immutable  
       brush.Freeze(); 
{

شما نباید مقدار property brush Object را تغییر دهید زیرا این کار باعث ایجاد خطای nvalidOperationException خواهد شد.

یک راه دیگر برای تنظیمات، استفاده از XAML است.

<SolidColorBrushx: Freeze="True"  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"/>  

مثال های بیشتر :

    Button button = new Button();  
    SolidColorBrush brush = new SolidColorBrush(Colors.Blue);  
    if (brush.CanFreeze)  
    {  
        // Makes the brush unmodifiable.  
        brush.Freeze();  
    }  
    button.Background = brush;  
    if (brush.IsFrozen) // Evaluates to true.  
    {  
        // If the brush is frozen, create a clone and modify the clone.  
        SolidColorBrushbrushClone = brush.Clone();  
        brushClone.Color = Colors.Red;  
        button.Background = brushClone;  
    }  
    else  
    {  
        brush.Color = Colors.Yellow; // Change the Property as object is not Frozen  
{

یک مثال دیگر را هم در زیر می توانیم ببینیم:

BitmapImage image = new BitmapImage(new Uri("ABC.jpg”,UriKind.RelativeOrAbsolute));  
    var image2 = new Image();  
    Image2.Source = image;   
    grid.Children.Add(image2);  
    this code looks absolute fine. However this code is potential source of memory leak due to statement grid.Children.Add(image);  
    Rewrite of this code would be:  
      
    BitmapImage image = new BitmapImage(new Uri("ABC.jpg”,UriKind.RelativeOrAbsolute));  
    var image2 = new Image();  
    Image2.Source = image;   
    If (image.CanFreeze)  
    {  
       image.Freeze();// this will save the memory leak.  
    }  
    grid.Children.Add(image2);  

دانلود نسخه ی PDF این مطلب