سلام
حتما در برنامه های ما زمانی وجود دارد که باید اشیاء دیگری که توسط شی جاری خود ایجاد کرده ایم را ببندیم، برای مثال شی ای که ورود و خروج کاربران را در شبکه کنترل می نماید یا در موارد بسیار ساده تر زمانی که باید Connection موجود بین برنامه و DB را در انتهای برنامه ببندیم و چندین و چند مثال دیگر ...
برای انجام چنین وظایفی، باید با استفاده از متود Finalize و Dispose (بعدا توضیح می دهم) و همچنین استفاده از کلاس Garbage Collector موجود در Framework چنین کارهایی را انجام دهیم.

متود Finalize چیست؟
Finalize متود ویژه ای است که Garbage Collector قبل از خارج کردن شی از درون Heap Memory آن را فراخوانی می نماید. این متود کم و بیش شبیه رویداد Class_Terminate در Visual Basic 6 می باشد. اما تفاوت هایی نیز وجود دارد. در VB6 بلافاصله بعد از قرار دادن شی به Nothing شی رویداد Class_Terminate را فراخوانی می نماید ولی حال این قضیه صادق نمی باشد.
به طور کل تمامی اشیاء موجو در .NET Framework متود Finalize را از کلاس System.Object به ارث می برند به همین دلیل در زمان استفاده از متود Finalize دو خصوصیت Protected و Overrides را به کار برید.

برنامه ای که در پایین مشاهده می نمایید نحوه استفاده از متود Finalize را بهتر نشان می دهد. برای دیدن نحوه کار مناسب برنامه لطفا مراحل زیر را انجام دهید.
1. پروژه ی جدیدی را در .Net باز نمایید.
2. ویندوز فرم Form1 را از پروژه حذف نمایید.
3. کلاسی با عنوان Person ایجاد نمایید.
4. ماژولی نیز با عنوان MainModule ایجاد نمایید.
5. در Property Page برنامه، خاصیت Startup Object را روی Sub Main تنظیم نمایید.


Public Class Person
Public FirstName As String
Public LastName As String

Protected Overrides Sub Finalize()
MyBase.Finalize()
Debug.WriteLine("Person " & Me.FirstName & " " & Me.LastName & " is being destroyed.")
End Sub

Public Sub New(ByVal fn As String, ByVal ln As String)
Me.FirstName = fn
Me.LastName = ln
End Sub
End Class



Public Module MainModule
Public Sub Main()
Call TestFinalize()
Debug.WriteLine("About to terminate the application")
End Sub

Public Sub TestFinalize()
Debug.WriteLine("About to create a Person object.")
Dim myPerson As New Person("Shasa", "Marandi")
myPerson = Nothing
Debug.WriteLine("Exiting the Test Finalize procedure.")
End Sub
End Module



6. دگمه F5 را فشار دهید.
7. نتیجه را در پنجره Output ببینید.


About to create a Person object.
Exiting the Test Finalize procedure.
About to terminate the application
Person Shasa Marandi is being destroyed.


همانطور که متوجه شدید به علت اینکه Garbage Collector تنها زمانی فعال می شود، که یا برنامه برای ایجاد اشیاء جدید به حافظه بیشتری احتیاج داشته باشد و یا زمانی که خود برنامه Terminate شود. به همین علت باید به این نکته توجه نماییم :
در متود Finalize هیچ شی جدیدی را ایجاد یا فراخوانی ننمایید. بدلیل اینکه شی منبع به طور کامل از بین می رود پس خود شی جدید نیز به عنوان یک Garbage شناسایی می شود و امکان برخورد با یک Exception پدید می آید.

روش فراخوانی دستی Garbage Collector از طریق برنامه :
برای فراخوانی Garbage Collector می توان به دو طریق عمل کرد :
1. ایجاد متناسب اشیاء اضافی برای ایجاد کمبود در Heap Memory و ضرورت استفاده System از Garbage Collector.
2. فقط کافیه به Garbage Collector اعلام کنیم تا دستور را انجام دهد !؟؟؟

برای این کار در داخل .NET Framework کلاسی تحت عنوان GC وجود دارد که دارای متودهای مختلفی است. مهم ترین این متود ها عبارتند از Collect و WaitForPendingFinalizers و SuppressFinalize (در زمان شرح متود Dispose این متود را توضیح می دهم). کد پرسیجر TestFinalize را به صورت زیر تغییر دهید.


Public Sub TestFinalize()
Debug.WriteLine("About to create a Person object.")
Dim myPerson As New Person("Shasa", "Marandi")
myPerson = Nothing
Debug.WriteLine("About to fire a garbage collection.")
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub



حال برنامه را دوباره اجرا نمایید. و نتیجه را مشاهده نمایید.

About to create a Person object.
Person Shasa Marandi is being destroyed.
Exiting the Test Finalize procedure.
About to terminate the application


متود Collect که مشخص است دستور جمع آوری را صادر می نماید و اما متود WaitForPendingFinalizers اجرای برنامه را تا Finalize صحیح همه اشیاء اضافی موجود در Heap Memory متوقف می نماید.
ذکر این نکته لازم است که استفاده مکرر از کلاس GC نمی تواند ایده مناسبی برای برنامه ما باشد زیرا GC.Collect() سبب جستجوی مکرر در Heap Memory می گردد تا با پیدا کردن اشیاء اضافی آنها را Finalize نمایید، لذا این مسئله در برنامه های بزرگ باعث از بین رفتن یکی از خصوصیات مثبت Framework جدید یعنی Optimizing (بهینه بودن) می گردد. توصیه می شود تنها در زمانی که برنامه در حالت بیکاری به سر می برد از این متود استفاده نمود به عنوان مثال می توان به زمان انتظار برنامه برای ورود اطلاعات از طرف کاربر اشاره نمود).

خسته نباشید، به امید خدا بقیه مبحث مربوط به Finalize اشیاء را در بحث دیگری (احتمالا با نام کلاس های استاندارد چه نوع کلاس هایی می باشند؟) بررسی می نمایم.