تفاوت بین using , dispose
ایا بین using و dispose فرقی هست
مثلا بنویسیم
using (System.IO.MemoryStream ms = new ...)
{
...
}
یا
System.IO.MemoryStream ms = new ....
....
ms.Dispose();
این دو تا یک کارو انجام میدن یا نه؟
نقل قول: تفاوت بین using , dispose
dispose متد نابود کننده ست
این لینک رو مطالعه کنید
نقل قول: تفاوت بین using , dispose
نقل قول:
نوشته شده توسط
hamid_hr
ایا بین using و dispose فرقی هست
مثلا بنویسیم
using (System.IO.MemoryStream ms = new ...)
{
...
}
یا
System.IO.MemoryStream ms = new ....
....
ms.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();
}
}
نقل قول: تفاوت بین using , dispose
حالا باید از اینها استفاده کرد یا نه؟
چون خود #C چیزی داره که خودش خود به خود فضاهای اشغال شده رو پاک می کنه (GC).
نقل قول: تفاوت بین using , dispose
نقل قول:
نوشته شده توسط
forodo
حالا باید از اینها استفاده کرد یا نه؟
چون خود #C چیزی داره که خودش خود به خود فضاهای اشغال شده رو پاک می کنه (GC).
GC فقط Managed Resources رو آزاد میکنه ولی وقتی یک کلاس، Unmanaged Resources (مثل File Handle و ...) داره، باید IDisposable رو پیادره سازی کنه و در نهایت، استفاده کننده از اون کلاس با استفاده از using یا فراخوانی Dispose باعث میشه Unmanaged Resources آزاد بشه.
البته در مورد مثالی که زدن، MemoryStream منابع مدیریت نشده نداره و احتمالا Dispose نکردن سریح اون مشکلی ایجاد نمیکنه، ولی استفاده از using باعث میشه که این اطمینان وجود داشته باشه که هیچ ارجاعی به اون شی باقی نمیمونه و GC میتونه اون شی رو Collect کنه.
کلا Dispose کردن سریح اشیایی که IDisposable هستن (چه با using چه با try...finally) توصیه میشه.
نقل قول: تفاوت بین using , dispose
نقل قول:
نوشته شده توسط
plus
GC فقط Managed Resources رو آزاد میکنه ولی وقتی یک کلاس، Unmanaged Resources (مثل File Handle و ...) داره، باید IDisposable رو پیادره سازی کنه و در نهایت، استفاده کننده از اون کلاس با استفاده از using یا فراخوانی Dispose باعث میشه Unmanaged Resources آزاد بشه.
Managed Resources و Unmanaged Resources چیه؟
و لطفاً به این پست هم جواب بدید.
نقل قول: تفاوت بین using , dispose
نقل قول:
نوشته شده توسط
forodo
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 باعث میشه که منابع مدیریت نشده اون شی آزاد بشه و البته اون شی دیگه قابل استفاده نخواهد بود.
نقل قول: تفاوت بین using , dispose
نقل قول:
نوشته شده توسط
plus
به طور خلاصه، منظور از 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 از حافظه کامپیوتر پاک می شه؟
نقل قول: تفاوت بین using , dispose
نقل قول:
نوشته شده توسط
forodo
خیلی ممنون بابت توضیحاتتون.
پس یعنی اگر شی را با استفاده از new درست کنیم اصلاً کاری به اون شی نداشته باشیم چون فضای اشغال شده توسط اون شی خود به خود آزاد می شه مثل:
ali a = new ali();
SqlConnection con = new SqlConnection();
DataSet ds = new DataSet();
TextBox tb = new TextBox();
PersianCalendar pc = new PersianCalendar();
ولی موقعی که از توابع API استفاده می کنیم خودمون باید فضا رو آزاد کنیم.
درست گفتم؟
1) اگه کلاس مورد نظر شما IDisposable رو پیاده سازی نکرده باشه، مثل کلاس ali، شما کلا نمیتونید Dispose رو انجام بدین چون چنین متدی اصلا وجود نداره.آزاد سازی رو GC زمانی که خودش تشخیص بده انجام میده.
2) اگه کلاس مورد نظر IDisposable رو پیاده کرده باشه، شما "میتونید" که بعد از اینکه کارتون رو با شی انجام دادین اصلا کاری بهش نداشته باشید.در نهایت GC با تشخیص خودش متد Dispose شی رو فراخوانی میکنه و منابع Unmanaged شی آزاد میشه و حافظه اختصاص داده شده هم که Managed Resource هست باز توسط GC آزاد میشه.
ولی به این نکته توجه کنید که شی ای که ایجاد کردین احتمالا منابع Unmanaged ی رو در اختیار داره که بهتره هرچه زودتر آزاد بشن. (برای مثال یک SqlConnection یک ارتباط با دیتابیس ایجاد کرده) بنابراین که اگه شما دیگه احتیاجی به اون شی ندارین، بهتره که بلافاصله با فراخوانی Dispose (یا استفاده از using) باعث بشین تا "منابع مدیریت نشده" آزاد بشن.
دقت کنید که فراخوانی Dispose باعث نمیشه حافظه Managed اختصاص داده شده به شی همون موقع آزاد بشه.حافظه مدیریت شده، همونطور که از اسمش پیداس توسط GC مدیریت میشه و فازغ از اینکه شما Dispose رو فراخوانی کنید یا نه در زمان غیر قابل پیشبینی آزاد میشه.
درضمن منابع مدیریت نشده لزوما توسط توابع API اختصاص داده نمیشن...
نقل قول:
نوشته شده توسط
forodo
حالا متد dispose کداش چیه؟
در مورد 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;
}
}
همونطور که میبینید دو محل برای ازاد سازی منابع مدیریت شده و مدیریت نشده هست که بایستی توسط کلاس مورد نظر پیاده ب
نقل قول:
نوشته شده توسط
forodo
و اگر نخوایم از کلاس اینترفیس IDisposable ارث بری کنه، می تونیم توی برنامه اینطوری بنویسیم؟
کلاسی داریم که کداش اینه:
class ali
{
public void alireza()
{
messagebox.show("test");
}
}
|
|
حالا که ما توی این کلاس متد dispose نداریم توی برنامه از using استفاده کنیم همون کار رو انجام می ده؟
using (ali a=new ali())
{
a.alireza();
}
|
|
خیر، کلاس شما اگه IDisposable نباشه نمیتونید اصلا در using قرارش بدین.
نقل قول:
نوشته شده توسط
forodo
الان اینجوری فضای اشغال شده توسط شی a از حافظه کامپیوتر پاک می شه؟
خیر، باز هم میگم، با فراخوانی Dispose یا استفاده از using حافظه اختصاص داده شده به شی (که جزو Managed Resource) هست آزاد نمیشه، فقط منابع مدیریت نشده آزاد میشن.
حافظه اختصاص داده شده به شی در هر صورت توسط GC و در زمان غیر قابل پیش بینی آزاد میشه.
نقل قول: تفاوت بین using , dispose
واقعاً متشکرم که وقت گذاشتید.
الان کاملاً گرفتم چی شد.
فقط یه چیز رو درست متوجه نشدم.
از کجا می شه فهمید منابع مدیریت شده و مدیریت نشده کدوما هستند.
مثلاً گفتید که ارتباط با بانک یه منبع مدیریت نشدست.
بقیه رو از کجا می شه فهمید؟
نقل قول: تفاوت بین using , dispose
من خودم هر شی رو که ایجاد میکنم وقتی کارم باهاش تموم شد اگه متد dispose داشت اجرا میکنم
نقل قول: تفاوت بین using , dispose
نقل قول:
نوشته شده توسط
hamid_hr
من خودم هر شی رو که ایجاد میکنم وقتی کارم باهاش تموم شد اگه متد dispose داشت اجرا میکنم
ایول.
همون قضیه کار از محکم کاری عیب نمی کنه.
پس اگر برای هر کلاس تابع dispose را درست کنیم و همه جای برنامه بعد از تمام شدن کارمون با شی که در اصل می شه آخر بلوکی که شی در اون قرار داشته شی رو dispose کنیم مشکلی پیش نمیاد.
بازم ممنون.