PDA

View Full Version : گفتگو: در مورد استفاده از try,catch



hossein_ignore
جمعه 25 تیر 1389, 09:41 صبح
سلام اساتید محترم(منظورم از اساتید همتونید)

من تو جواب سوال یکی از اعضا از try استفاده کردم که ازم ایراد گرفتن! پیش خودم فکر کردم تا یه تاپیک ایجاد کنم تا همه نظر خودشونو در این مورد بگن تا از try در جای خودش بهترین استفاده رو کرد . . .


(اگه کسی از چیزی که می خواد بگه اطمینان حاصل نکرد خواهشا اون مطلب رو بیان نکنه)

mahdi_7610
جمعه 25 تیر 1389, 10:21 صبح
سلام

خوب اون سوال چی بود؟

چه ایرادی گرفتن؟

hossein_ignore
جمعه 25 تیر 1389, 10:41 صبح
سلام

خوب اون سوال چی بود؟

چه ایرادی گرفتن؟

اون سوالو بیخیال! کلا می خوایم در مورد try بحث کنیم . . .

sds1920
جمعه 25 تیر 1389, 10:54 صبح
این تاپیک رو بخون.مطالب خوبی توش هست.
http://barnamenevis.org/forum/showthread.php?t=224485

ahrimaneahurai
جمعه 25 تیر 1389, 10:55 صبح
خب try catch چیز خوبیه ؟ در مورد چیش آخه می خوای بحث کنیم ؟ استفاده از این دستورمگه عیبی هم داره؟

shima2006
جمعه 25 تیر 1389, 10:58 صبح
سلام اساتید محترم(منظورم از اساتید همتونید)

من تو جواب سوال یکی از اعضا از try استفاده کردم که ازم ایراد گرفتن! پیش خودم فکر کردم تا یه تاپیک ایجاد کنم تا همه نظر خودشونو در این مورد بگن تا از try در جای خودش بهترین استفاده رو کرد . . .


(اگه کسی از چیزی که می خواد بگه اطمینان حاصل نکرد خواهشا اون مطلب رو بیان نکنه)


به خاطر ایجاد این تاپیک ازتون بسیار سپاسگذارم ، منم خیلی دلم میخواد راجع به TRY -CATCH بیشتر بدونم....
شاید بد نباشه از این سوال شروع کنیم که دلیل اصلی استفاده از TRY-CATCH چیه؟؟کجا باید ازش استفاده کنیم و کجا استفاده نکنیم؟؟؟

sds1920
جمعه 25 تیر 1389, 11:05 صبح
به خاطر ایجاد این تاپیک ازتون بسیار سپاسگذارم ، منم خیلی دلم میخواد راجع به TRY -CASH بیشتر بدونم....
شاید بد نباشه از این سوال شروع کنیم که دلیل اصلی استفاده از TRY-CASH چیه؟؟کجا باید ازش استفاده کنیم و کجا استفاده نکنیم؟؟؟

برای کنترل خطاهای مدیریت نشده در برنامه استفاده می شه.
توی تاپیک بالا که گفتم همه ی اینها نوشته شده.

mahdi_7610
جمعه 25 تیر 1389, 11:10 صبح
به خاطر ایجاد این تاپیک ازتون بسیار سپاسگذارم ، منم خیلی دلم میخواد راجع به TRY -CASH بیشتر بدونم....
شاید بد نباشه از این سوال شروع کنیم که دلیل اصلی استفاده از TRY-CASH چیه؟؟کجا باید ازش استفاده کنیم و کجا استفاده نکنیم؟؟؟

سلام

به طور خیلی خلاصه از try و catch برای کنترل خطا استفاده می شه .

شما میتونید هنگامی که کدی برای قسمتی از برنامه می نویسید احتمال وقول خطا را پیش بینی کنید .

مثلا شما توی قسمتی از برنامه از کاربر می خواهید عدد وارد کنه اما احتمال میدید کاربر به جای عدد از حروف استفاده کنه . در این صورت ممکنه برنامه شما دچار اشکال بشه و برنامه شما بسته بشه بدون اینکه کاربر دلیل این کار را متوجه بشه .

حالا شما قسمتی از برنامه را که احتمال میدید دچار خطا بشه را داخل بلوک try قرار میدید و عکس العمل خودتون را ( پیغامی را به کاربر می دید و دلیل خطا را بهش گوشتزد می کنید .) را داخل بلوک catch قرار میدید .

موفق باشید .

moh_mov
جمعه 25 تیر 1389, 11:11 صبح
سلام
خوب چیز خوبیه....
باعث میشه برناممون اررور هاش ، باعث ارور وحشی نشه و بشه ارور ها رو کنترل کرد...گاها ارور ها لازمند (مانند خواندن از پورت سریال!)پس ما باید بتونیم ارور هامون رو هندل کنیم!

hossein_ignore
جمعه 25 تیر 1389, 11:30 صبح
اینم من اضافه کنم که وقتی یکی(حداقل یکی) از کدهای داخل try با Error مواجه شه، کدهای داخل catch اجرا میشه

ehsanara
جمعه 25 تیر 1389, 14:26 عصر
پیغامی که موقع خطا توی Catch نشون داده میشه میتونه برای رفع خطا بدرد بخور باشه و بدونی کجای برنامه یا پایگاه ایراد داره
من خودم از این نوع توی Catch استفاده می کنم




MessageBox.Show(Owner,"String","Caption",MessageBoxButtons.Button,MessageBoxIcon.Icon, MessageBoxDefaultButton.defaultbutton,MessageBoxOp tions.Option)

FastCode
جمعه 25 تیر 1389, 16:32 عصر
try
{
EXECUTENONQUERY("DELETE FROM TABLE_X WHERE ID = " + txtbox1.Text);
EXECUTENONQUERY("INSERT INTO TABLE_X(" + txtbox1.Text + ", " + txtbox2.Text + ")");
}
catch{}

توی این مثال فکر کنید که مقدار تکستباکس اول ""و مقدار تکستباکس دوم مثلا" "1" باشه.
شاید مثال خوبی نباشه ولی این مثالها فراوانند.

Amir Oveisi
جمعه 25 تیر 1389, 16:37 عصر
دو نوع خطا در برنامه هایی که می نویسیم وجود داره:

Compile-time Error
Run-time Error


Compile-time Error:
خطاهایی هستند که در زمان کامپایل اتفاق می افتند و کامپایلر قادر به تشخیص آن می باشد. مانند Syntax error ها. که همگی با آن آشنا هستید و نیاز به توضیح ندارد.

Run-time Error:
این خطاها بر خلاف خطاهای زمان کامپایل، توسط کامپایلر قابل تشخیص نیستند. کد شما از نظر کامپایلر خطایی ندارد و اجرا می شود. اما ممکن است در زمان اجرا خطایی که از دید کامپایلر پنهان مانده بود آشکار شود. کد زیر را در نظر بگیرید که در آن دو عدد صحیح از کاربر گرفته می شود و حاصل تقسیم آن ها به کاربر نشان داده می شود:

int num1 = Int32.Parse(Console.ReadLine());
int num2 = Int32.Parse(Console.ReadLine());
int num3 = num1 / num2;
Console.WriteLine(num3.ToString());


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

با توجه به مطالب بالا، برای کنترل Exception ها (Exception Handling)، از try-catch در C#‎‎ استفاده می کنیم.
فطعه کدی را که احتمال بروز Exception در آن وجود دارد در داخل بلوک try قرار می دهیم و بلافاصله بعد از آن بلوک catch را قرار می دهیم.
با این کار اگر در کدهای بلوک try یک خطای زمان اجرا اتفاق بیفتد، در بلوک catch مدیریت خواهد شد.

نحوه استفاده صحیح از Exception Handling:
برای هر خطای زمان اجرا (Exception) در دات نت یک کلاس طراحی شده است که همه آن ها از کلاس پایه ای به اسم Exception ارث می برند. مثلا برای مثال ذکر شده، کلاسی به اسم DividedByZeroException وجود دارد.
اگر یک exception در بلوک try رخ دهد، آن Exception به شرطی در بلوک catch مدیریت خواهد شد که بلوک Catch، قابلیت مدیریت آن نوع Exception را داشته باشد. در واقع ما در زمان ایجاد بلوک catch مشخص می کنیم که چه نوع Exception ای در این catch، مدیریت خواهد شد. فرض کنید DividedByZeroException در بلوک try اتفاق افتاده و ما در بلوک catch مشخص کرده ایم که NullReferenceException را مدیریت خواهیم کرد. در اینصورت، خطای تقسیم بر صفر در بلوک catch مدیریت نخواهد شد.
حال فرض کنید متد A در داخل متد B فراخوانی می شود. در متد A یک Exception رخ می دهد اما در متد A هیچ عمل catch ای انجام نمی شود، در اینصورت این Exception به سمت متد B حرکت می کند و اگر در متد B مدیریت نشود به همین ترتیب به سمت بیرون حرکت می کند تا به متد Application.Run در کلاس Program برسد و اگر در آنجا نیز catch نشد، برنامه crash خواهد کرد زیرا هیچ مدیریتی بر روی exception رخ داده انجام نداده است.

چند مثال:

...
try
{
//some codes here
}
catch(DividedByZeroException ex)
{
//do something here
}



- این کد exception های تقسیم بر صفر را Catch می کند.


...
try
{
//some codes here
}
catch(DividedByZeroException ex)
{
//do something here
}
catch(NullReferenceException ex)
{
//do something here
}


- این کد دو نوع Exception تقسیم بر صفر و null refernce را catch می کند.


برای توضیحات کامل تر به لینک زیر مراجعه نمایید:
http://msdn.microsoft.com/en-us/library/0yd65esw(VS.80).aspx

FastCode
جمعه 25 تیر 1389, 16:53 عصر
...
try
{
//some codes here
}
catch(DividedByZeroException ex)
{
//do something here
}

رو میتونیم بنویسیم:


...
if(x != 0)
{
//some codes here
}
else
{
//do something here
}
که سرعتش حد اقل 200 برابره.و کدش کمتره.

Amir Oveisi
جمعه 25 تیر 1389, 17:11 عصر
که سرعتش حد اقل 200 برابره.و کدش کمتره.

لطفا بحث رو منحرف نکنید. این هم صرفا یک مثال بود.

با تشکر

hossein_ignore
جمعه 25 تیر 1389, 18:34 عصر
از همه اونایی که تو بحث شرکت میکنن ممنونم.

یه سوالی واسم پیش اومده! اینکه ما تو catch نوع خطا رو مشخص کنیم چه مضایایی داره نسبت به این که هیچ پارامتری واسه catch نذاریم؟

Amir Oveisi
جمعه 25 تیر 1389, 19:11 عصر
در حالتی که شما نوع خطا رو مشخص نکنید خوب طبیعتا همه exception ها رو catch می کنه و شما نمیدونین که حالا این exception ای که رخ داده چی هست. مثلا اگر در یک قطعه کدی دارین یه عمل convert از string به int انجام میدین که محتویات string هم از یک فایل خونده میشه. حالا شما کل این کد رو با یه catch ساده گرفتینش (یا به اصطلاح Generic Exception Handling انجام دادین).
حالا اگر exception ای رخ بده مثلا اینجا بگیم دو حالت داره، یا اون string مقداری داره که نمیشه به عدد تبدیلش کرد (InvalidFormatException اگر اشتباه نکنم) یا اینکه اصلا فایل وجود نداره (FileNotFoundException).
اما شما نمیتونین بفهمین که کدوم اتفاق افتاده، و در نتیجه نمیدونین تو catch چکار کنید و چه راه حلی برای این مشکل اتخاذ کنید.

بنابراین همیشه سعی کنید از Generic Exception Handling دوری کنید. چون تا زمانی که میشه به شکل دقیق تر کاری رو انجام داد دلیلی نداره دقت کار رو بیاریم پایین.


برای اطلاع بیشتر در مورد این بحث، مطلب زیر رو بخونید:
http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
موفق باشید.

hossein_ignore
جمعه 25 تیر 1389, 21:45 عصر
پس تعیین نوع Exception تو سرعت catch تاثیری نداره! درسته؟

اگه ما خودمون Errorهارو پیش بینی کنیم و یه جوری از رخ دادنشون جلوگیری کنیم بهتره یا از try,catch استفاده کنیم؟ مثلا بجای FileNotFoundException اینطوری کد بنویسیم :
if(
System.IO.File.Exists(string Path)
)

hossein_ignore
جمعه 25 تیر 1389, 22:15 عصر
...
try
{
//some codes here
}
catch(DividedByZeroException ex)
{
//do something here
}

رو میتونیم بنویسیم:


...
if(x != 0)
{
//some codes here
}
else
{
//do something here
}
که سرعتش حد اقل 200 برابره.و کدش کمتره.

رو چه حسابی میگی سرعتش 200 برابره؟

Masoome_das
جمعه 25 تیر 1389, 23:49 عصر
اگه منم بخوام نظرم را بگم
من try و catch را برای این بکار میبرم که در بعضی مواقع خطاهایی در برنامه اتفاق می افتد که کاربر را دچار سرگردانی می کند کاربر متوجه نمی شود که این خطا بخاط اشتباه در عمل کرد خودش اتفاق افتاده یا اینکه مربوط به مشکلات خود سیستم است مثل خواندن یک مقدار Null با DataReader کابر که مفهوم خطایی که سیستم بهش نشان میده را که نمیفهمه پس شاید بارها برنامه را اجرا کنه و مشکلش حل نشه یا اصلا از نرم افزار ناامید بشه پس در این جور مواقع ما باید با پیش بینی درست به کاربر و پشتیبان سیستم کمک کنیم تا خطا را براحتی درک کنند و کنترلش کنند .
بیش تر این دسته خطاها در ارتباطات با DB خواندن و نوشتن اطلاعات اتفاق می افتد.

moh_mov
دوشنبه 28 تیر 1389, 08:04 صبح
سلام...
اما به نظر میاد try catch ها سرعت ران برنامه رو شدیدا میارن پایین....
من دارم بهینه می کنم یه پروژه رو.....با حذف try catch ها و استفاده از روش بهتر برنامم سرعت اون تابعش از حدود 14 ثانیه به 2 ثانیه رسید.....(البته cpu استفاده شده ، ضعیف بود اما دیگه!)

FastCode
چهارشنبه 30 تیر 1389, 16:46 عصر
رو چه حسابی میگی سرعتش 200 برابره؟
اون پستی که حذف شد نشون میده که سرعتش ۶۰۰۰۰۰ برابره.
ولی ۲۰۰ برابر برای زمانیه که پردازش دیگه ای هم وجود داشته باشه.

Amir Oveisi
چهارشنبه 30 تیر 1389, 18:45 عصر
اون پستی که حذف شد نشون میده که سرعتش ۶۰۰۰۰۰ برابره.

در پست مذکور شما داخل یک حلقه از try-catch استفاده کرده بودید که کار کاملا اشتباهیه.
استفاده از try-catch برای مدیریت exception ها اگر به شیوه ای نادرست انجام نشه، تاثیر ناچیزی بر روی performance داره و مشکلی بوجود نمیاره. اما عرض کردم، به شرطی که درست ازش استفاده بشه.

این رو حتما مطالعه کنید : Performance Tips and Tricks in .NET Applications (http://msdn.microsoft.com/en-us/library/ms973839.aspx)

این رو هم ببینید بد نیست، یک تست در این مورد انجام شده: Speed Test: Try / Catch Block (http://www.blackwasp.co.uk/SpeedTestTryCatch.aspx)

FastCode
چهارشنبه 30 تیر 1389, 19:31 عصر
در پست مذکور شما داخل یک حلقه از try-catch استفاده کرده بودید که کار کاملا اشتباهیه.
استفاده از try-catch برای مدیریت exception ها اگر به شیوه ای نادرست انجام نشه، تاثیر ناچیزی بر روی performance داره و مشکلی بوجود نمیاره. اما عرض کردم، به شرطی که درست ازش استفاده بشه.

این رو حتما مطالعه کنید : Performance Tips and Tricks in .NET Applications (http://msdn.microsoft.com/en-us/library/ms973839.aspx)

این رو هم ببینید بد نیست، یک تست در این مورد انجام شده: Speed Test: Try / Catch Block (http://www.blackwasp.co.uk/SpeedTestTryCatch.aspx)
خیلی جالبه.
شما یه چیزی گفتی که با یه شرط ساده حل میشد, من هم گفتم که اگر قرار باشه فقط exception raise کنه اینطوری میشه.
ولی مثالی که شما زدی هیچ exception ی raise نمیکرد و کاملاً UNFAIR بود, به چند دلیل:
اولین دلیل این که کدها توی حلقه اول JIT میشدن.
دوم این که optimaization توی خیلی از حالت ها تمام کد درون حلقه رو برمیداره.
سوم اینکه معلوم نیست اونها تست رو در چه کانفیگی اجرا کردن.
چهارم این که modulus یه الگوریتم سنگین داره که باعث میشه کم بودن سرعت در try/catch به چشم نیاد
پنجم اینکه چون این مثال در حلقش از یه شیء توی heap استفاده کرده سرعت عملاً هیچ کاری نمیکنه و اون یک ذره اختلاف میتونه به علت اختلاف سرعت رم و سی پی یو باشه.

و ششم این که شما کد من رو که اگر اجراش میکردی اعداد جالبی رو نشون میداد رو حذف کردی.

واقعاً غیر منسفانست.

در ضمن چه اسراری وجود داره که مردم رو تشویق کنید از try/catch استفاده کنن؟
و اینکه چرا یه لینک به اون comparation هایی که نتایجشون عکس لینک شماست ندادید؟

یادم رفت بگم که لینک اول به اندازه من سن داره:August 2001

Amir Oveisi
چهارشنبه 30 تیر 1389, 22:56 عصر
ولی مثالی که شما زدی هیچ exception ی raise نمیکرد و کاملاً UNFAIR بود
کدوم مثال؟!


واقعاً غیر منسفانست.
اگر پاک شدن پستتون منظورتونه باید عرض کنم که پست شما مسیر تاپپک رو داشت منحرف می کرد (که البته باز هم اینطور شد) به همین دلیل حذف شد.
اگر مایل به ادامه بحث و تبادل نظر در این مورد هستید لطفا یک تاپیک جدید با موضوع مناسب ایجاد کنید تا با دوستان به ادامه بحث بپردازیم. بنده شدیدا مشتاق به همکاری در اون تاپیک خواهم بود.


در ضمن چه اسراری وجود داره که مردم رو تشویق کنید از try/catch استفاده کنن؟
هیچ اصراری وجود نداره و من هیچوقت چنین کاری نکردم. سعی کنید کلی به فضیه نگاه کنید و با یک مثال، نتیجه گیری کلی انجام ندید.


یادم رفت بگم که لینک اول به اندازه من سن داره
بعضی چیزها تاریخ مصرف ندارند.

موفق باشید

علیرضا مداح
پنج شنبه 31 تیر 1389, 08:35 صبح
سلام،
خوب مطلبی که آقای اویسی گفتند، صرفا" جهت نمایش یک ویژگی بود(For Demonstration Purpose)،
اما از طرف دیگر ذکر این نکته ضروری هست که شما باید تا جایی که می توانید، از بروز Exception جلوگیری نمایید، به قطعه کد زیر توجه کنید:
try
{
string text = System.IO.File.ReadAllText("C:\\test.txt");
// ...
}
catch (System.IO.FileNotFoundException)
{
// Do Something Here
}
خوب در اینجا چون فایل مذکور بر روی سیستم من وجود ندارد، بدنه ی catch اجرا می شود، اما من می توانستم در ابتدا چک کنم که این فایل وجود دارد یا خیر و دیگر نیازی هم به Handle کردن FileNotFoundException نبود:
if (System.IO.File.Exists("c:\\test.txt"))
{
// Do Something...
}
T/