نوشته شده توسط
SajjadKhati
سلامی مجدد
this ، اشاره گر به شی Form_3 تون هست دیگه . درسته؟
طبعا شیِ Form_3 تون را هم در رویداد دکمه ای که در پست 1 گفته بودید ، خودتون شیِ جدید بهش دادین (new Form_3() کردین) دیگه . درسته؟
اگه درسته ، در این حالت ، اینکه متد Dispose اش را فراخونی کردین ، درسته .
اما اگه این ، شی ای بود که توسط کدهای ویژال استودیو نوشته میشد (یعنی خودتون مستقیما شی ایجاد نمیکردید و new نمیکردید) ، لازم نبود متد Dispose را فراخونی کنید .هر چند ، در این حالت هم اشکال چندانی هم نداشت .
- دوما ، جای مناسب فراخونیِ متد Dispose ، توی رویدادِ خود اون شی یا کنترل زیر مجموعه های اون شی نیست . یعنی رویداد Form Close ئه Form_3 ، جای خوبی برای فراخونی متد Dispose نیست .
جای مناسب اش ، بعد از اتمام کارش هست . یعنی بعد از اینکه متد Form_3_ShowDialog را فراخونی کردین ، بعد از این متد ، فراخونی متد Dispose ئه Form_3 ، بهترین جاش هست .
راحت تر هست براتون که Form_3 را توی دستور using بذارید تا مجبور نباشید متد Dispose را فراخونی کنید .
- سوما ، GC.Collect ، ای که در رویداد form close ئه Form_3 نوشتید ، هیچ تاثیری در پاک کردن داده های Managed ئه Form_3 در اینجا نداره :
چون اولا شما در رویداد form close ئه Form_3 هستید و هنوز دارید از شیِ Form_3 استفاده میکنید .
دوما و مهمتر اینکه شما تا اون موقع ، قطعا اشاره گر به شیِ Form_3 را null نکردین و از بین نبردین و قطعا تا اون موقع ، حداقل یک اشاره گر ، به شیِ Form_3 تون داره اشاره میکنه چون رویداد form close ئه Form_3 در حال اجرا شدن هست .
باید همه ی متغییرهایی که به اون شی اشاره میکنن را اول ، null کنید تا هیچ اشاره گری به اون شی اشاره نکنه و بعدش متد GC.Collect را اجرا کنید .
جای فراخونی این متدِ GC.Collect هم بعد از فراخونی متد Dispose (یا بعد از دستور using) ، اول ، همه ی متغییرهایی که به اون شی از Form_3 اشاره دارن را null میکنید و بعد از null کردنِ همه شون ، حالا متد GC.Collect را فراخونی میکنید (که در همون رویداد دکمه ای که در پست 1 گفتین ، میشه) .
ضمنا ، با فراخونی این متد ، شما صرفا درخواست پاک سازی دادید . نه اینکه در همون لحظه پاکسازی انجام میشه .
- چهارما ، دقت کنید که همه ی کنترل ها و کلا همه ی اشیاهایی که خودتون در کدنویسی ، مقدار جدید بهشون دادین را هم این کار را انجام بدین براشون .
فرضا ممکنه در یک رویدادی در Form_3 ، یک Button ای را شی جدید داده باشید که در این صورت وظیفه ی شماست که بعد از استفاده ، متد Dispose اش را فراخونی کنید . همچنین حتی برای اینکه حافظه ی Managed اش را آزاد کنید ، بعد از اون ، فرضا اگه در متغییر سراسری تعریف کردید ، وظیفه ی شماست که اول ، null اش کنید و بعد متد GC.Collect را فراخونی کنید .
همچنین هر شی دیگه ای (نه فقط کنترل ها) .
مشکلش را در بالا گفتم .
این هم مشکلش همون هست .
منتها دقت کنید که خیلی از چیزها ، حافظه را اشغال میکنن که کلا جزء برنامه تون ممکنه حساب بشه از جمله clr ئه برنامه و ... .
اشاره گر ، null شدنی نیست .
متغییرها ، null شدنی هستن . اگه متغییرها null بشن ، اشاره گرشون به شی مورد نظر را از دست میدن .
منظورم ، هر شی ای که اینترفیس IDisposable را پیاده سازی کرده باشه که در نتیجه متد Dispose داره ، هست . از شی SqlDataAdapter گرفته تا Form و کنترل ها و ... .
اگه باز درست نشد ، ممکنه جایی را برای همین روالی که توضیح داده شد ، برای شی یا اشیاهای دیگه اشتباه کرده باشین که میتونین از برنامه ی مدیریت حافظه ی ویژال استودیو کمک بگیرین .
خیلی خیلی ممنونم ازت سجاد جان. خیلی کاربردی بود. ممنونم از لطفت.
قسمت اول توضیحاتتون : من فقط توی فرم 2 یه دکمه گذاشتم برای فراخوانی فرم 3 که اطلاعات توش نمایش میده
الان طبق چیزایی که گفتین اومدم یه سری تغییرات دادم :
1. توی Form2 یه دکمه ای داشتم که تو رویدادش این کد رو نوشتم برای فراخوانی Form3 :
using (var frm3 = new Form3())
{
frm3.ShowDialog();
frm3.Dispose();
GC.Collect();
}
GC.Collect(); رو در رویداد form closing فرم 3 کلاً پاک کردم.
تا اینجا درست هست؟
چجوری میتونم اشاره گر به شیِ Form_3 را null کنم؟
گفتید که : همه ی متغییرهایی که به اون شی از Form_3 اشاره دارن را null میکنید.
منطورتون همون frm3 رو باید null کنم ؟؟
- چهارما ، دقت کنید که همه ی کنترل ها و کلا همه ی اشیاهایی که خودتون در کدنویسی ، مقدار جدید بهشون دادین را هم این کار را انجام بدین براشون.
منظورتون چی بود که گفتین این کار ها رو باید براشون انجام بدم؟ یعنی بیام تو هر رویداد Dispose کنم و GC.Collect رو فراخوانی کنم ؟ میشه یه مثال بزنید؟
ممنون از پاسخگویی و صبورتیون.