PDA

View Full Version : فرق بلاک using با بلاکهای ایونتها



میلاد قاضی پور
جمعه 09 مهر 1389, 19:06 عصر
سلام . وقتی میخوایم فضا بعد از استفاده از یک نمونه آزاد بشه و نیازی به فراخوانی تابع dispose نداشته باشیم میایم از بلاک using {} استفاده میکنیم . اما آیا این بلاک که در خارج از اون متغیر ها از بین رفته تلقی میشن همون کاری رو انجام میدن که توی ایونت ها هم انجام میشه ؟ مثلا توی ایونت باتون_کلیک یک اینستنس از یک کلاس ایجاد شده . بعد از تمام شدن کار کامپایل کدها دیگه اون اینستنس نابود میشه اینطور نیست ؟ خب اگه جواب بلی هست آیا لازم هست ما باز هم از بلاک using{} استفاده کنیم ؟ یا انشالله از یوزینگ وقتی استفاده میشه که کدهای زیادی برای کامپایل باشه و نیاز داشته باشیم بعد از کامپایل یک سری کد و ایجاد شدن نمونه و انجام شدن مأموریت مورد نظر سریعا فضا رو آزاد داشته باشیم تا وقتی نوبت به کدهای بعدی میرسه حافظه زیادی اشغال نبوده باشه ؟

mehdi.mousavi
جمعه 09 مهر 1389, 23:08 عصر
سلام.
بعنوان یک قانون کلی، شما همواره باید روی کلیه کلاسها یا Component هایی که اینترفیس IDisposable رو پیاده سازی کرده اند، متود Dispose رو فراخوانی کنید. این فراخوانی لزوما به معنای آزادسازی حافظه در همون لحظه نیست، در واقع بخش مدیریت حافظه هستش که تصمیم میگیره کی و در چه فازی، حافظه رو به سیستم برگردونه. جدا از مسائل مربوط به حافظه، فراخوانی Dispose روی Instance ای از کلاسی که IDisposable رو پیاده سازی کرده، منجر به وقوع شرایط متفاوتی میشه.

بطور مثال، در SqlConnection باعث میشه تا Connection به Connection Pool برگرده، در Stream ها باعث میشه تا فایل (یا Stream مورد نظر) بسته بشه، در GDI Object ها باعث میشه تا Handle مربوطه به سیستم برگرده و ...

در حقیقت، شما بعنوان یه برنامه نویس خوب، همواره باید Resource مورد نظرتون رو به محض اینکه کارتون باهاش تموم شد به سیستم برگردونید. از اینجا به بعد GC تصمیم میگیره که کی و به چه صورت حافظه رو به سیستم برگردونه، اما با اینکار شما پیشاپیش به سیستم اعلام کرده اید که دیگه با Resource مورد نظر کاری ندارید و ...

در مورد Compile و Event Handler و ... حقیقتش متوجه سوالتون نشدم. اگر بیشتر توضیح بدید بهتون پاسخ خواهم داد.

موفق باشید.

پاورقی: برای اطلاعات بیشتر در مورد IDisposable به این پست (http://barnamenevis.org/forum/showthread.php?p=417952) رجوع کنید. شاید این تاپیک (http://barnamenevis.org/forum/showthread.php?t=212157)نیز بهتون اطلاعات بیشتری در این خصوص بده.

میلاد قاضی پور
شنبه 10 مهر 1389, 02:23 صبح
10 خط نوشته بودم زدم ثبت شه میگه نوشته شما اندک است .از اول:

میگم آیا داخل هر تابعی که صد خط کد داره و ممکنه تا تمام کدها اجرا بشن حافظه کم بیاریم باید حافظه رو آزاد کنیم یا همیشه اصولا اینکار حتی در توابعی که کدهای ساده ای توشون هست هم انجام میشه ؟

سوأل بعدی: با بسته شدن یک بلاک از تابع مگه خود به خود متغیر ها و اشیای محلیش نابود نمیشن؟ اگر جواب بلی هست لازمه اونجا هم با وجود نابودی خودکار ما هم اقدام به آزادسازی حافظه کنیم یا خیر؟

mehdi.mousavi
شنبه 10 مهر 1389, 10:22 صبح
میگم آیا داخل هر تابعی که صد خط کد داره و ممکنه تا تمام کدها اجرا بشن حافظه کم بیاریم باید حافظه رو آزاد کنیم یا همیشه اصولا اینکار حتی در توابعی که کدهای ساده ای توشون هست هم انجام میشه ؟

عرض کردم، بعنوان یک قانون کلی، شما همواره باید هر Resource ای رو، به محض اینکه دیگه بهش احتیاج نداشتید آزاد کنید. (اینکه این Resource کی و چگونه به سیستم برگرده وظیفه GC هستش و شما نباید نگران این مساله باشید). مساله مهم از دید شما، فراخوانی Dispose روی Object ای هستش که IDisposable رو پیاده سازی کرده. خواه دو خط کد نوشته باشید، خواه 200 خط. اگر به Resource ای نیاز ندارید، هر چه سریعتر از شرش خلاص بشید، بهتره.



سوأل بعدی: با بسته شدن یک بلاک از تابع مگه خود به خود متغیر ها و اشیای محلیش نابود نمیشن؟ اگر جواب بلی هست لازمه اونجا هم با وجود نابودی خودکار ما هم اقدام به آزادسازی حافظه کنیم یا خیر؟

GC تصمیم میگیره که در چه فازی و کی حافظه مربوطه رو به سیستم برگردونه. اما شما نباید منتظر اون باشید تا اون اینکارو برای شما انجام بده. برنامه شما باید شهروند خوبی در شهر حافظه باشه. اگر فرصت کنم، بعدا در مورد مدیریت حافظه براتون توضیحات کاملی میدم. فعلا، به این مساله پایبند باشید که اگر کلاسی IDisposable رو پیاده سازی کرده بود، شما متود Dispose اش رو به محض اینکه کارتون با اون Object پایان پذیرفت، فراخوانی کنید.

موفق باشید.