www.doronamir.com

E-mail: doron@doronamir.com

 

 

IDisposable & Destructor  

 

פונקציה זו דורסת את פוקציית ה Finalize המוגדרת ב Object , תפקיד פונקציית ה Destructor להגדיר פעולות אחרונות לפני ניקוי האובייקט

ה Destructor אינה מופעלת בזמן ידוע ומנוהלת ע"י ה Garbage Collector , ניתן להשתמש במתודה Collect  של המחלקה GC

ובכך לאלץ את ה Garbage Collector לאסוף מיידית את האובייקטים שאין להם התייחסות .

 

בתכנית הנ"ל ניתן לראות כי עבור אובייקט p1 לא הייתה התייחסות ( ( null  ובגלל הקריאה ל Collect  ה Destructor  של  אובייקט זה הופעלה

לעומתו אובייקט p2 מכיל עדיין התייחסות בשלב הרצת התכנית , הקריאה ל Destructor מתבצעת רק בעת סגירת התכנית .

 

 

 

 

using System;

 

namespace Doron1

{

    class Person

    {

        string Name;

 

        public Person(string name)

        {

        this.Name=name;

        }

 

        public void SayHello()

        {

        Console.WriteLine("Hello From {0}",this.Name);

        }

 

        ~Person()

        {

        Console.WriteLine("{0} Destructor",this.Name);

        }

 

    }

 

    class MainClass

    {

   

        static void Main(string[] args)

        {

       

            Person p1 = new Person("Person A");

            Person p2 = new Person("Person B");

            p1.SayHello();

            p2.SayHello();

            p1=null;

            GC.Collect();

            Console.ReadLine();

        }

    }

}

 

למעשה ה Destructor מתורגם למתודת ה Finalize של Object כלומר מבצע דריסה , אם ננסה לבצע דריסה ל Finalize נקבל שגיאה כגון :

Do Not override object.Finalize . Instead provide a destructor.

 

 

IDisposable

 

כאשר רוצים לשחרר אובייקט מיידית כמו התקשרות ל DB או לקבצים אנו לא נבחר ב Destructor  מיכוון שתזמון הפעלתו אינו ידוע , לכן ניתן להשתמש במתודת Dispose שיש לממש אותה דרך ממשק IDisposable ,מתודה זו מאפשרת לנו לקרוא לה במפורש עבור ביצוע ניקוי האובייקטים כלומר הסרת התייחסות ע"י null וקריאה למתודה GC.collect , ניתן למנוע הפעלת destructor קיים ע"י הפעלת המתודה GC.SuppressFinalize() בכך נמנע פעולת ניקוי ע"י ה Destructor אם המתודה dispose נקראה לפני כן .

 

בתכנית הנ"ל ניתן לראות כי המחלקה מכילה Destructor ויורשת ממשק IDisposable המחייב לממש את המתודה Dispose

המתודה Dispose מכילה קריאה למתודה GC.SuppressFinalize() בכדי למנוע הפעלת ה Destructor

לאחר פעולת ה Dispose , ה Destructor  יופעל אם לא תתבצע קריאה ל Dispose .

 

    public class Person:IDisposable

    {

        public Person()

        {

        Console.WriteLine("Pesron- object Constructor ");

        }

       

        public void Dispose()

        {

        Console.WriteLine("Pesron- object Dispose ");

        GC.SuppressFinalize(this);

        }

 

        ~Person()

        {

        Console.WriteLine("Pesron- object Destructor ");

        }

 

    }

ניתן לראות בקוד הנ"ל כי קיימת קריאה מפורשת ל Dispose וכי למרות אי ההתייחסות לאובייקט וקריאה ל Collect  לא יופעל ה Destructor

בכדי למנוע כפילות תפקידים.

class ClassMain

    {

   

        [STAThread]

        static void Main(string[] args)

        {

            Person p1 = new Person();

            p1.Dispose();

            p1=null;

            GC.Collect();

        }

    }