PDA

View Full Version : استفاده کارآمد از دستور Using برای آزاد سازی بهتر منابع



habedijoo
چهارشنبه 17 اسفند 1384, 10:46 صبح
سلام به همه دوستان عزیز

مدیریت منابع و آزادسازی اشیاء یکی از بحث های مهم برنامه نویسی ست . توصیه میکنم حتما مطالب این سرفصل رو پیگیری کنید .
به هر حال زمانی که از یک کلاس ، شی ساخته میشود حتما پس از استفاده می باید آنرا از بین برد و منابع مورد استفاده اش را آزاد کرد .
هر چند که وقتی یک کلاس را خراب میکنید در همان لحظه توسط کامپایلر منابعش آزاد نمی شود .
حال نمونه کد زیر را در نظر بگیرید



TextReader reader = new StreamReader(filename);
String line ;
While ((line=reader.ReadLine()) !=null)
{
Console.WriteLine(line);
}
Reader.close ;

این کد یک مشکل اساسی دارد . در واقع در برابر exception ایمن نیست . اگر فراخوانی ReadLine یا WriteLine مشکلی ایجاد کند آنگاه متد close فراخوانی نمیشود .

برای بهینه شدن این کد بدین شکل عمل میشود .


TextReader reader = new StreamReader(filename);
Try
{
String line ;
While ((line=reader.ReadLine()) !=null)
{
Console.WriteLine(line);
}
}
Finally
{
Reader.close ;
}


با این کد حتی اگر خطایی هم رخ دهد متد Close اجرا خواهد شد .

اما استفاده از Finally چند مشکل دارد .
1 – اگر مجبور باشید چند منبع را آزاد کنید این روش ناکارآمد است .
2 – فهم راه حل مشکل است و هر بار باید تکرار شود .
3 - در خیلی از مواقع لازم است در کد تغییرات زیادی انجام دهید .
4 – ارجاع به منبع حتی بعد از بلاک Finally هم باقی میماند . یعنی ممکن است بعد از آزاد شدن منبع تصادفا مورد استفاده واقع شود . زیرا که منبع در سراسر برنامه قابل دسترسی است .

اما استفاده از دستور Using برای بهینه شدن این کد .



Using ( try variable = initialization ) embeddedStatement


این دستور معادل دستورات زیر است :




{
Type variable = initialization ;
Try
{
embeddedStatement
}
Finally
{
If (variable != Null)
{
((Disposable)variable).Dispose();
}
}
}



پس بهترین راه برای اینکه مطمئن شوید متد Close همیشه فراخوانی شود به شکل زیر است :



Using(TextReader reader = new StreamReader(filename)
{
String line ;
While((line = reader.ReaderLine()) != )
{
Console.WriteLine(line);
}
}


مزایای این روش :
1 – برای آزاد سازی چندین منبع به خوبی کار می کند .
2 – منطق برنامه را خراب نمی کند
3- از تکرار جلوگیری میکند .
4 – بعد از دستور Using دیگر نمیتوان از منبع استفاده کرد . زیرا آن منبع در خارج از محدوده Using قابل دسترسی نیست . ( * این مورد بهترین مزیت این دستور است زیرا یکی از پر اشکال ترین موارد در آزاد سازی منابع استفاده تصادفی دوباره از آن منبع است . )

پایدار باشید .

HO457
چهارشنبه 17 اسفند 1384, 11:18 صبح
مرسی هدایت جان، مطلب جالبی بود. :گل:

Milad Mohseny
جمعه 19 اسفند 1384, 01:04 صبح
مرسی خیلی عالی بود

مطهر
جمعه 19 اسفند 1384, 20:33 عصر
مطلب خوبی بود.ارزش خوندن را داشت


هر چند که وقتی یک کلاس را خراب میکنید در همان لحظه توسط کامپایلر منابعش آزاد نمی شود .
به نظر شما این حرف درسته؟؟
منابع سیستم توسط کامپایلر آزاد نمیشه؟

reza_rad
شنبه 20 اسفند 1384, 08:47 صبح
متشکر آقای عابدی جو. مفید بود.

habedijoo
شنبه 20 اسفند 1384, 09:04 صبح
هر چند که وقتی یک کلاس را خراب میکنید در همان لحظه توسط کامپایلر منابعش آزاد نمی شود .

آقای مطهر سلام .
منظورم را دقیقتر بگویم این است که وقتی شما یه کلاس را Dispose میکنید آنن و در لحظه منابع آن توسط کامپایلر آزاد نمیشود .
در واقع Garbage Collector است که منابع سیستمی کلاس ها را از بین میبرد . و جالب این است که برنامه نویس دقیقا نمیداند که Garbage Collector چه زمانی این کار را انجام میدهد .

mom alone
یک شنبه 02 فروردین 1388, 17:30 عصر
اگه بخاهیم یک متغییر رو بعدا هم استفاده کنیم چی؟
می شه یه راه بگید که در هنگام فرم close حتما اشیاء حذف شوند

rezatati
سه شنبه 04 فروردین 1388, 10:58 صبح
با سلام خدمت دوستان
ولی میشه هروقت که بخواهیم عملیات Garbage Collection را در #C انجام بدیم با دستور زیر


GC.Collect();