ایا بین using و dispose فرقی هست
مثلا بنویسیم
using (System.IO.MemoryStream ms = new ...)
{
...
}
یا
System.IO.MemoryStream ms = new ....
....
ms.Dispose();
این دو تا یک کارو انجام میدن یا نه؟
ایا بین using و dispose فرقی هست
مثلا بنویسیم
using (System.IO.MemoryStream ms = new ...)
{
...
}
یا
System.IO.MemoryStream ms = new ....
....
ms.Dispose();
این دو تا یک کارو انجام میدن یا نه؟
dispose متد نابود کننده ست
این لینک رو مطالعه کنید
کد دومی که ارائه کردین معادل کد اول نیست.در صورتی که بین new و Dispose یک Exception اتفاق بیافته Dispose اجرا نمیشه در صورتی که در using این طور نیست.
این دو کد معادل هستن:
using (MemoryStream ms = new MemoryStream()) {
...
}
MemoryStream ms = null;
try {
ms = new MemoryStream();
...
}
finally {
if (ms != null) {
ms.Dispose();
}
}
در مورد اینکه کدوم بهتره هم، اگه شما نیازی نداشته باشی که Exception های ایجاد شده رو Catch کنی، استفاده از using خلاصه تر هست، ولی در صورتی که نیاز به کنترل Exception های ایجاد شده داشته باشی استفاده از using مناسب نیست چون مجبور میشی یک try..catch دیگه داخل using ی که خودش معادل try...finally هست بگذاری.
در حالت دوم کدی شما با try finally میشه :
MemoryStream ms = null;
try {
ms = new MemoryStream();
...
}
catch (IOException ex) {
Console.WriteLine("An exception occured: " + ex.Message);
}
finally {
if (ms != null) {
ms.Dispose();
}
}
حالا باید از اینها استفاده کرد یا نه؟
چون خود #C چیزی داره که خودش خود به خود فضاهای اشغال شده رو پاک می کنه (GC).
GC فقط Managed Resources رو آزاد میکنه ولی وقتی یک کلاس، Unmanaged Resources (مثل File Handle و ...) داره، باید IDisposable رو پیادره سازی کنه و در نهایت، استفاده کننده از اون کلاس با استفاده از using یا فراخوانی Dispose باعث میشه Unmanaged Resources آزاد بشه.
البته در مورد مثالی که زدن، MemoryStream منابع مدیریت نشده نداره و احتمالا Dispose نکردن سریح اون مشکلی ایجاد نمیکنه، ولی استفاده از using باعث میشه که این اطمینان وجود داشته باشه که هیچ ارجاعی به اون شی باقی نمیمونه و GC میتونه اون شی رو Collect کنه.
کلا Dispose کردن سریح اشیایی که IDisposable هستن (چه با using چه با try...finally) توصیه میشه.
Managed Resources و Unmanaged Resources چیه؟
و لطفاً به این پست هم جواب بدید.
به طور خلاصه، منظور از Managed Resources (منابع مدیریت شده)، همون Managed Memory یا حافظه مدیریت شده هست که توسط Garbage Collector مدیریت میشه (وقتی هیچ Reference (ارجاع)ی به یک شی نباشه حافظه اون شی آزاد میشه).
Unmanaged Resources هر منبع دیگه ای هست که البته بر خلاف Managed Resources، دیگه Garbage Collector چیزی ازش نمیدونه و نمیتونه مدیریتش کنه.
برای مثال، وقتی شما یک شی رو با استفاده از new ایجاد میکنید، Garbage Collector از حافظه اختصاص داده شده و ارجاهات به اون شی اطلاع داره و به موقع اون رو از حافظه خارج میکنه...در این حالت شما نگران آزاد کردن این منبع به اصطلاح Managed Resource نیستید.
ولی وقتی شما منبع دیگه ای رو در اختیار میگیرین (برای نمونه، ایجاد یک فایل با Windows API) شما مسئول مدیریت و آزاد سازی اون منبع که به اصطلاح Unmanaged Resource هست، میشین.بنابرین کلاسی که این منبع رو در اختیار میگیره و مدیریت میکنه بایستی IDisposable رو پیاده سازی که و در متد Dispose این منابع Unmanaged رو آزاد کنه چون GC نمیتونه این آزاد سازی رو انجام بده.
--
پاسخ اون پست رو هم دوستان دادن، this به شی جاری اشاره میکنه و به طور کلی فراخوانی Dispose باعث میشه که منابع مدیریت نشده اون شی آزاد بشه و البته اون شی دیگه قابل استفاده نخواهد بود.
خیلی ممنون بابت توضیحاتتون.
پس یعنی اگر شی را با استفاده از new درست کنیم اصلاً کاری به اون شی نداشته باشیم چون فضای اشغال شده توسط اون شی خود به خود آزاد می شه مثل:
ali a = new ali();
SqlConnection con = new SqlConnection();
DataSet ds = new DataSet();
TextBox tb = new TextBox();
PersianCalendar pc = new PersianCalendar();
ولی موقعی که از توابع API استفاده می کنیم خودمون باید فضا رو آزاد کنیم.
درست گفتم؟
................................
نه منظورم در اون پست استفاده از using رو dispose که مثال زدم . اینجا دوباره قرارش می دم.
کدهایی که باید داخل کلاس بنویسیم برای اینکه متد Dispose رو داشته باشیم چیه؟
می دونم باید کلاس رو اینطوری بنویسیم:
class ali : IDisposable
حالا متد dispose کداش چیه؟
و اگر نخوایم از کلاس اینترفیس IDisposable ارث بری کنه، می تونیم توی برنامه اینطوری بنویسیم؟
کلاسی داریم که کداش اینه:
class ali
{
public void alireza()
{
messagebox.show("test");
}
}
حالا که ما توی این کلاس متد dispose نداریم توی برنامه از using استفاده کنیم همون کار رو انجام می ده؟
using (ali a=new ali())
{
a.alireza();
}
الان اینجوری فضای اشغال شده توسط شی a از حافظه کامپیوتر پاک می شه؟
1) اگه کلاس مورد نظر شما IDisposable رو پیاده سازی نکرده باشه، مثل کلاس ali، شما کلا نمیتونید Dispose رو انجام بدین چون چنین متدی اصلا وجود نداره.آزاد سازی رو GC زمانی که خودش تشخیص بده انجام میده.
2) اگه کلاس مورد نظر IDisposable رو پیاده کرده باشه، شما "میتونید" که بعد از اینکه کارتون رو با شی انجام دادین اصلا کاری بهش نداشته باشید.در نهایت GC با تشخیص خودش متد Dispose شی رو فراخوانی میکنه و منابع Unmanaged شی آزاد میشه و حافظه اختصاص داده شده هم که Managed Resource هست باز توسط GC آزاد میشه.
ولی به این نکته توجه کنید که شی ای که ایجاد کردین احتمالا منابع Unmanaged ی رو در اختیار داره که بهتره هرچه زودتر آزاد بشن. (برای مثال یک SqlConnection یک ارتباط با دیتابیس ایجاد کرده) بنابراین که اگه شما دیگه احتیاجی به اون شی ندارین، بهتره که بلافاصله با فراخوانی Dispose (یا استفاده از using) باعث بشین تا "منابع مدیریت نشده" آزاد بشن.
دقت کنید که فراخوانی Dispose باعث نمیشه حافظه Managed اختصاص داده شده به شی همون موقع آزاد بشه.حافظه مدیریت شده، همونطور که از اسمش پیداس توسط GC مدیریت میشه و فازغ از اینکه شما Dispose رو فراخوانی کنید یا نه در زمان غیر قابل پیشبینی آزاد میشه.
درضمن منابع مدیریت نشده لزوما توسط توابع API اختصاص داده نمیشن...
در مورد IDisposable میتونید اینجا مطالعه کنید: http://msdn.microsoft.com/en-us/libr...isposable.aspx
IDispsable رو به این صورت میشه پیاده کرد:
class MyDisposableClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
}
همونطور که میبینید دو محل برای ازاد سازی منابع مدیریت شده و مدیریت نشده هست که بایستی توسط کلاس مورد نظر پیاده ب
خیر، کلاس شما اگه IDisposable نباشه نمیتونید اصلا در using قرارش بدین.
خیر، باز هم میگم، با فراخوانی Dispose یا استفاده از using حافظه اختصاص داده شده به شی (که جزو Managed Resource) هست آزاد نمیشه، فقط منابع مدیریت نشده آزاد میشن.
حافظه اختصاص داده شده به شی در هر صورت توسط GC و در زمان غیر قابل پیش بینی آزاد میشه.
واقعاً متشکرم که وقت گذاشتید.
الان کاملاً گرفتم چی شد.
فقط یه چیز رو درست متوجه نشدم.
از کجا می شه فهمید منابع مدیریت شده و مدیریت نشده کدوما هستند.
مثلاً گفتید که ارتباط با بانک یه منبع مدیریت نشدست.
بقیه رو از کجا می شه فهمید؟
من خودم هر شی رو که ایجاد میکنم وقتی کارم باهاش تموم شد اگه متد dispose داشت اجرا میکنم