PDA

View Full Version : رها کردن کامل منابع بعد از بستن فرم



FreeMagic
دوشنبه 16 بهمن 1391, 14:02 عصر
من توی چند تا فرم دارم
یه قسمت از برنامه فرم دوم رو این طوری نشون میدم
frmd_members_ned frm = new frmd_members_ned();
frm.ShowDialog();

این طوری هم همون فرم دوم رو میبدنم
this.Close();
ولی وقتی دوباره همین فرم دوم رو باز میکنم به دلیل اینکه منابع قبلی ازاد نشدن پیغام خطا میده و خارج میشه
ترجمه پیغامش هم اینه که این منابع توسط پروسه دیگه ای در حال استفاده هستن
ولی از این دستور که استفاده میکنم منابع کامل آزاد میشه
Application.Restart();
هرچند همونطور که از اسمش پیداست گند میزنه به پروژه و کاربر باید از اول لاگین کنه و ............
ممنون میشم راهنماییم کنید که منابع کامل ازاد بشن

morteza5358
دوشنبه 16 بهمن 1391, 14:06 عصر
سلام
فکر کنم این مشکلت حل بشه:
this.Dispose();
این فرمت رو نابود میکنه!

موفق باشی

samadblaj
دوشنبه 16 بهمن 1391, 14:08 عصر
سلام از این دو تیکه کد استفاده کنید...

Application.ExitThread();

برای آزاد کردن منابع شی خاص...

this.Dispose();
conecction.Dispose();

FreeMagic
دوشنبه 16 بهمن 1391, 14:18 عصر
سلام
فکر کنم این مشکلت حل بشه:
this.Dispose();
این فرمت رو نابود میکنه!

موفق باشی

اینم امتحان کردم مثل this.close(); عمل میکنه


سلام از این دو تیکه کد استفاده کنید...

Application.ExitThread();

برای آزاد کردن منابع شی خاص...

this.Dispose();
conecction.Dispose();

اینا الان سه تیکه شدن یعنی سه دستور
شی خاص هم که درگیر منابع هست picturebox هست
الان چه طوری استفاده کنم؟

AMIN_SG
دوشنبه 16 بهمن 1391, 14:23 عصر
سلام
picturebox.dispose();

FreeMagic
دوشنبه 16 بهمن 1391, 14:28 عصر
سلام
picturebox.dispose();

اینم جواب نمیده
خیلی ور رفتم باهاش:گریه:

morteza5358
دوشنبه 16 بهمن 1391, 14:28 عصر
سورس رو بزار.....

the king
دوشنبه 16 بهمن 1391, 17:37 عصر
using (frmd_members_ned frm = new frmd_members_ned())
{
frm.ShowDialog();
}
GC.Collect();


مطمئن شوید که اگر در جایی بجز این فرم frmd_members_ned متغیری دارید که با یک عضو از این frmd_members_ned
در ارتباطه، بعد از ShowDialog حتما اون متغیر رو برابر null کنید تا هیچ شیء ای بخاطر اون متغیر باقی نمونه.

ordebehesht
دوشنبه 16 بهمن 1391, 18:06 عصر
از application.colse() استفاده کردی
appliction.exite() هم بدر میخوره

در ضمن چرا میخوای منابع رو آزاد کنی خود C# اینکار رو به طور اتوماتیک کمیکنه

RED-C0DE
دوشنبه 16 بهمن 1391, 22:24 عصر
شما کنترلی روی آزاد کردن لحظه ایه منابع Managed ندارین فقط ممکنه روند آزادسازی رو تسریع ببخشین.
خود موتور داخلی .net در زمان مناسب اینکارو انجام می ده.

همونطور هم ک گفتن نیازی هم واسه این کارا روی منابعی ک خود .net روی اونها و مصرف حافظشون نظارت و مدیریت داره نیست..
این آبجکتهای ب اصطلاح Managed ، هنگامی ک دیگه ریفرنس زنده ای بهشون نباشه یا از Scope حیات خودشون خارج بشن، GC با الگوریتمهای هوشمندی طی زمانهایی ک خودش تشخیص می ده ب بهترین شکل حافظه اشغال شده توسط اونها رو مدیریت می کنه تا برنامه نویس درگیر این کارهای سیستمی و کلیشه ای نشه (البته مسلما هرچی بیشتر بدونیم بهتره ) و فکرش فقط سمت توسعه هر چ بهتر منطق برنامه خودش باشه.

اما برای بعضی از منابع با ارزش و هزینه بر و منابعی ک خارج از دسترس این موتور آشغال جمع کن .net یا همون Garbage Collector هستند ، مثل کانکشن ب بانک اطلاعاتی، منابع و کامپوننت های COM (مثل کار با اکتیو ایکس های قدیمی و ساختارهای سنتی ) ، کار با فایلها ، منابع تحت شبکه ، ... بهتره فکری برای مدیریت اونها سمت برنامه توسط برنامه نویس بشه...


Understanding Garbage Collection in .NET
(http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/)

RED-C0DE
دوشنبه 16 بهمن 1391, 22:38 عصر
ی پیشنهاد برای ادامه کاراتون ،
از پروفایلرها کمک بگیرید و استفاده کنید جدا از کارای دیگه ای ک می کنید.
بهتون کمک می کنه ببینید پشت صحنه چ اتفاقاتی داره می افته .مثل مصرف حافظه، توابع و کلاسها و خطوط کد پر هزینه (از لحاظ زمانی/حافظه ای) ، ... و در بعضی برنامه ها هم در همین راستا بهتون پیشنهادهایی برای هر چ بهتر و بهینه تر شدن برنامتون می دن...

خود Profiler ک ی مفهوم کلیه، اما در اینجا می تونین برای مثال از CLR Profiler (http://www.microsoft.com/en-us/download/details.aspx?id=13382) استفاده کنید

FreeMagic
سه شنبه 17 بهمن 1391, 19:05 عصر
در کل من توی یه قسمتی از برتامه قراره مشخصات اعضا رو برای ثبت بگیرم از جمله عکسشون
عکس انتخابی کاربر رو که از طریق اپن دیالوگ میگیرم توی یکی از پوشه های خود پروژه کپی و در picturebox نمایش میدم.
ممکنه کاربر یه عکس رو انتخاب و بعد پشیمون بشه بخواد یه عکس دیگه انتخاب کنه به خاطر همین چند عکس به پوشه پروژه اضافه میشه.
هر بار که این فرم باز میشه عکس های به درد نخور قبلی رو قراره پاک کنه در صورتی که اگه کل برنامه باز و بسته نشه امکان حذف اون عکسا (حتی از طریق خود ویندوز) وجود نداره
میخوام وقتی فرم بسته شد و دوباره فرم باز شد (بدون اینکه application بسته بشه) بتونم عکس های اضافی رو پاک کنم در صورتی که نمیشه
خلاصه کدهای مربوط به کارم اینا هستن:
از این کد برای نمایش فرم ثبت اعضا استفاده میکنم
frmd_members_ned frm = new frmd_members_ned();
frm.ShowDialog();
از این کد هم برای کپی عکس انتخاب شده به پوشه های محلی پروژه استفاده میکنم
OpenFileDialog od = new OpenFileDialog();
od.Filter = "Image File|*.jpg;*.gif;*.bmp;*.png";
if (od.ShowDialog() == DialogResult.OK)
{
string patch,fn,fe,t = od.SafeFileName;
int l = t.Length;
fe = t[l - 4].ToString() + t[l - 3].ToString() + t[l - 2].ToString() + t[l - 1].ToString();
fn = t.Remove(l - 4);
DateTime nowdt = DateTime.Now;
string nows = nowdt.Year.ToString() + "_" + nowdt.Month.ToString() + "_" + nowdt.Day.ToString() + "_";
nows += nowdt.Hour.ToString() + "_" + nowdt.Minute.ToString() + "_" + nowdt.Second.ToString() + "_" + nowdt.Millisecond.ToString();
this.Text = nows;
patch = "..\\members_pic\\temp\\"+nows+fe;
File.Copy(od.FileName , patch , true);
pic_member.Image = Image.FromFile(patch);
pic_name = nows + fe;

}
خلاصه کد این هست که با توجه به تاریخ و زمان سیستم یه اسم خودم برای عکس انتخاب و به اونجا انتقال میدم
اگه کاربر عکس رو اشتباهی انتخاب کرد مسلما دوباره این کد تکرار میشه واسه انتخاب عکس بعدی

و از این کد هم در فرم لود گذاشتم که قبل از اجرای فرم عکس های اضافی رو پاک کنه
string[] files = Directory.GetFiles("..\\members_pic\\temp");
foreach (string s in files)
{
File.Delete(s);
}
حالا در صورتی که برای بار دوم فرم اجرا بشه به تنها دستور حلقه گیر میده و اونم اینه که فایل مورد نظر درگیر پروسه دیگه هست (البته اون موقع خود ویندوز هم نمیتونه پاکش کنه)

و در نهایت با یکی از فرم های زیر فرم رو می بندم و نتیجه اجرای همه کدها یکی هست
this.Dispose();
this.Close();

البته کد زیر هم جواب میده به جای دو دستور بالا ولی مشکلش اینه که کلا برنامه ریست میشه و این اصلا خوشایند نیست
Application.Restart();

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

FreeMagic
سه شنبه 17 بهمن 1391, 19:08 عصر
ضمنا وقتی چند عکس رو انتخاب میکنم برای اعضا (یعنی یه عکس انتخاب کردم و پشیمون شدم و عکس دیگه انتخاب کردم) اونوقت همه عکس ها درگیر پروسه میشن و هیچ جوری نمیشه هیچ کدومشون رو تا موقعی که برنامه باز هست پاک کرد. مگه اینکه برنامه بسته یا ریست بشه

plus
سه شنبه 17 بهمن 1391, 19:18 عصر
شما در رویداد Closed فرم، فکر نمیکنم دیگه نیازه به نمایش عکس PictureBox داشته باشی، میتونی اون رو از عکس جدا کنی:

protected override void OnClosed(EventArgs e)
{
if (this.pic_member.Image != null)
{
this.pic_member.Image.Dispose();
this.pic_member.Image = null;
}
}

اگه واقعا مشکل از عکس لود شده ار PictureBox باشه باید حل بشه.
پ.ن:
اگه باز هم مشکل داشتین احتمالا مشکل از Image.FromFile هست...از این بجاش استفاده کنید:

using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(patch)))
{
pic_member.Image = Image.FromStream(ms);
}

ordebehesht
سه شنبه 17 بهمن 1391, 19:19 عصر
برای اینکار از thread ببین میتونه کمکت کنه نمیگی همه عکسا درگیر پروسس میشن با ترد یکی یکی درگیر شن

FreeMagic
سه شنبه 17 بهمن 1391, 19:30 عصر
از thread بلدم استفاده کنم ولی در این مورد چه جوری استفاده کنم؟
کلا این این کدها به هیچ صراطی مستقیم نمیشن:لبخند:

ordebehesht
سه شنبه 17 بهمن 1391, 19:47 عصر
نمیدونم یه ایده دادم به تو

من خودم تازه ترد رو یادگرفتم فقط خواستم بگم ترد هم هست

FreeMagic
سه شنبه 17 بهمن 1391, 19:56 عصر
نمیدونم یه ایده دادم به تو

من خودم تازه ترد رو یادگرفتم فقط خواستم بگم ترد هم هست

من همین جوریش یه مشکل با پروسه در حال اجرا دارم. thread هم اضافه بشه پروسه ای که نمی بنده هیچ، یه پروسه دیگه هم اضافه میشه:لبخند:
هرچند فکر می کردم درست نمیشه ولی از قدیم گفتن در ناامیدی جای بسی امید هست. از اونم استفاده کردم ولی باز نتیجه ای نداشت

ordebehesht
سه شنبه 17 بهمن 1391, 19:57 عصر
شرمنده عزیز من فقط یه ایده دادم

FreeMagic
سه شنبه 17 بهمن 1391, 20:01 عصر
شرمنده عزیز من فقط یه ایده دادم
دشمنتون شرمنده
در حال حاضر هرچی ایده از اینجا و انجمن و گوگل و ... پیدا کردم هیچ جوابی نداد
نتیجه گرفتم که هروقت فایل قراره پاک بشه اسم و ادرس کامل رو توی یه جدول (جدولی که فقط یک فیلد داره) اضافه بکنم. اونوقت وقتی برنامه تازه اجرا میشه از روی این جدول ادرس ها رو بگیره و فایل ها رو پاک کنه. اونوقته که thread اساسی به درد میخوره:چشمک:
راست میگن در ناامیدی جای بسی امید است. شاید thread کارم رو راه ننداخت ولی ایده جدیدی که به ذهنم خورد فکر میکنم کارم رو راه بندازه. کمی سورس رو تغییر بدم ببینم جواب میده یا نه:متفکر:

plus
سه شنبه 17 بهمن 1391, 20:02 عصر
من همین جوریش یه مشکل با پروسه در حال اجرا دارم. thread هم اضافه بشه پروسه ای که نمی بنده هیچ، یه پروسه دیگه هم اضافه میشه:لبخند:
هرچند فکر می کردم درست نمیشه ولی از قدیم گفتن در ناامیدی جای بسی امید هست. از اونم استفاده کردم ولی باز نتیجه ای نداشت
مشکل شما همونی هست که گفتم...استفاده از Image.FromFile...نمیدونم حل نشد یا دیگه دنبال چی هستین؟

FreeMagic
سه شنبه 17 بهمن 1391, 20:13 عصر
مشکل شما همونی هست که گفتم...استفاده از Image.FromFile...نمیدونم حل نشد یا دیگه دنبال چی هستین؟
مشکل من این هست عکس هایی رو که با image.fromfile توی picturebox نمایش میده تا زمانی که کاملا برنامه بسته نشده اجازه پاک کردن اونا رو نمیده.
فرض کنید من اول عکسی رو کپی و بعد از طریق fromfile توی picturebox نمایش میدم و بعد دوباره عکس picturebox رو عوض میکنم. حالا وقتی میخوام عکس قبلی رو پاک کنم میگه که این عکس درگیر پروسه دیگه هست (خود ویندوز هم نمیتونه پاکش کنه)
الان مشکل من این هست که این عکس ها پاک بشن بدون اینکه کل برنامه کلا بسته بشه (فقط با ریست برنامه کار راه میفته که اصلا خوشایند نیست)
نمیدونم منظورم رو تونستم برسونم یا نه؟

plus
سه شنبه 17 بهمن 1391, 20:15 عصر
مشکل من این هست عکس هایی رو که با image.fromfile توی picturebox نمایش میده تا زمانی که کاملا برنامه بسته نشده اجازه پاک کردن اونا رو نمیده.
فرض کنید من اول عکسی رو کپی و بعد از طریق fromfile توی picturebox نمایش میدم و بعد دوباره عکس picturebox رو عوض میکنم. حالا وقتی میخوام عکس قبلی رو پاک کنم میگه که این عکس درگیر پروسه دیگه هست (خود ویندوز هم نمیتونه پاکش کنه)
الان مشکل من این هست که این عکس ها پاک بشن بدون اینکه کل برنامه کلا بسته بشه (فقط با ریست برنامه کار راه میفته که اصلا خوشایند نیست)
نمیدونم منظورم رو تونستم برسونم یا نه؟
دوست عزیز پست اول من رو اصلا خوندین؟

FreeMagic
سه شنبه 17 بهمن 1391, 20:23 عصر
راستش الان دیدمش ولی کد اولی که جواب نداد و این هم کد دوم شما هست
using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(patch)))
{
pic_member.Image = Image.FromStream(ms);
}
ولی توی این کد خود vs به patch گیر داده که فکر میکنم منظور شما آدرس کامل عکس هست؟ اگه منظور شما آدرس کامل عکس هست با چه عکسی بودین؟
عکس اضافه ای که کاربرد نداره باید ادرسش رو توی patch بزارم؟

plus
سه شنبه 17 بهمن 1391, 20:27 عصر
patch اسم متغیری هست که خودتون تعریف کردین!! چطور منظور ازش رو متوجه نمیشید.

OpenFileDialog od = new OpenFileDialog();
od.Filter = "Image File|*.jpg;*.gif;*.bmp;*.png";
if (od.ShowDialog() == DialogResult.OK)
{
string patch,fn,fe,t = od.SafeFileName;
int l = t.Length;
fe = t[l - 4].ToString() + t[l - 3].ToString() + t[l - 2].ToString() + t[l - 1].ToString();
fn = t.Remove(l - 4);
DateTime nowdt = DateTime.Now;
string nows = nowdt.Year.ToString() + "_" + nowdt.Month.ToString() + "_" + nowdt.Day.ToString() + "_";
nows += nowdt.Hour.ToString() + "_" + nowdt.Minute.ToString() + "_" + nowdt.Second.ToString() + "_" + nowdt.Millisecond.ToString();
this.Text = nows;
patch = "..\\members_pic\\temp\\"+nows+fe;
File.Copy(od.FileName , patch , true);
// pic_member.Image = Image.FromFile(patch);
using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(patch)))
{
pic_member.Image = Image.FromStream(ms);
}
pic_name = nows + fe;

}

FreeMagic
سه شنبه 17 بهمن 1391, 20:39 عصر
ببخشید فکر کردم منظورتون از patch یه ادرس دیگه هست:لبخند:
توی اون کدی که شما نوشتید مقدار patch آخرین عکسی هست که استفاده میشه. من توی کد جایگزینی شما ادرس یه عکس به دردنخور رو دستی گذاشتم. وقتی دوباره فرم رو اجرا کردم. همون مشکل پیش اومد یعنی باز گفت که درگیر پروسه دیگه هست:ناراحت:

ashrafi_j007
یک شنبه 25 اسفند 1392, 12:00 عصر
دوست عزیز بهترین کار اینه که شما به ازای هر بار که عکس مورد نظر رو در picture box عوض می کنین قبلش عکس قبلی اونو dispose کنین. مطمئن باشین که جواب میده. ;-)
یعنی به این صورت:
OpenFileDialog od = new OpenFileDialog();
od.Filter = "Image File|*.jpg;*.gif;*.bmp;*.png";
if (od.ShowDialog() == DialogResult.OK)
{
string patch,fn,fe,t = od.SafeFileName;
int l = t.Length;
fe = t[l - 4].ToString() + t[l - 3].ToString() + t[l - 2].ToString() + t[l - 1].ToString();
fn = t.Remove(l - 4);
DateTime nowdt = DateTime.Now;
string nows = nowdt.Year.ToString() + "_" + nowdt.Month.ToString() + "_" + nowdt.Day.ToString() + "_";
nows += nowdt.Hour.ToString() + "_" + nowdt.Minute.ToString() + "_" + nowdt.Second.ToString() + "_" + nowdt.Millisecond.ToString();
this.Text = nows;
patch = "..\\members_pic\\temp\\"+nows+fe;
File.Copy(od.FileName , patch , true);
pic_member.image.dispose();

pic_member.Image = Image.FromFile(patch);
pic_name = nows + fe;

}

hamid_hr
یک شنبه 25 اسفند 1392, 12:35 عصر
بهتره یه نگاه به تاریخش بندازین بعد جواب تایپیکو بدین

سه شنبه 17 بهمن 1391, 21:09 بعد از ظهر