مشخصات مقاله
-
2117
-
0.0
-
29749
-
0
-
0
آموزش مدیریت خطا Exception Handling در C#
وقتی با C# برنامهنویسی میکنی، همیشه همهچیز دقیقاً همونطور که انتظار داری پیش نمیره و ممکنه موقع اجرای برنامه با خطاهای مختلفی روبهرو بشی. توی چنین شرایطی، آشنایی با روش درست مدیریت خطاها کمک میکنه برنامه به شکل کنترلشدهتری با این اتفاقات برخورد کنه.
توی این مقاله قراره با مفهوم Exception و روش مدیریت اون در C# آشنا بشیم و ببینیم ساختارهایی مثل try-catch و finally چطور برای کنترل خطاهای زمان اجرا استفاده میشن. اگر در مسیر یادگیری C# هستی، Exception Handling یکی از مباحث مهمیه که برای نوشتن برنامههای قابل کنترلتر باید یاد بگیری.
آموزش مدیریت خطا Exception Handling در زبان C# :
در هر برنامهای ممکنه خطاهایی اتفاق بیفته و اجرای برنامه رو با مشکل مواجه کنه. در زبان C# یک کامپایلر هوشمند و کارآمد در اختیار داریم که میتونه جلوی بعضی از اشتباهات رایج رو بگیره. البته کامپایلر نمیتونه همه خطاهای موجود در کد رو شناسایی کنه و در چنین شرایطی، چارچوب کاری .NET یک خطا یا Exception اعلام میکنه تا به ما نشون بده بخشی از کد با مشکل مواجه شده. در درسهای قبل و در بخش آموزش کار با آرایهها Arrays در C#، دیدیم که چطور با وارد کردن آیتمهایی بیشتر از تعداد مشخصشده برای یک آرایه، میتونیم باعث ایجاد خطا در برنامه بشیم.
بیایید نگاهی به کد مثال بخش آموزش آرایهها در C# بندازیم:
using System;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[] numbers = new int[2];
numbers[0] = 23;
numbers[1] = 32;
numbers[2] = 42;
foreach(int i in numbers)
Console.WriteLine(i);
Console.ReadLine();
}
}
}
کد بالا رو اجرا کن تا ببینی برنامه خطا اعلام میکنه. مشکل این کد اینه که یک آرایه با دو عضو تعریف کردیم، اما در ادامه تلاش میکنیم سه عضو داخل اون قرار بدیم.
وقتی کد بالا رو در محیط یک IDE مثل Visual Studio اجرا کنی، برنامه چند راهحل یا توضیح درباره خطای ایجادشده بهت نشون میده. اما اگر برنامه رو با دابلکلیک روی فایل EXE اجرا کنی، ممکنه با یک خطای نامفهوم مواجه بشی و اجرای فایل متوقف بشه.
اگر احتمال میدی در بخشی از کدت خطایی اتفاق بیفته، باید بتونی اون خطا رو مدیریت کنی. اینجاست که Exception در C# به کمکمون میاد. کد مثال بالا رو کمی تغییر دادیم و به شکل زیر بازنویسی کردیم:
int[] numbers = new int[2];
try
{
numbers[0] = 23;
numbers[1] = 32;
numbers[2] = 42;
foreach(int i in numbers)
Console.WriteLine(i);
}
catch
{
Console.WriteLine("Something went wrong!");
}
Console.ReadLine();
حالا بیایید با یکی از کاربردیترین ابزارهای مدیریت خطا در C#، یعنی ساختار try-catch آشنا بشیم. یک بار دیگه برنامه رو اجرا کن و تفاوتش رو با دفعه قبل ببین. این بار به جای اینکه Visual Studio یا ویندوز نوع خطا رو به ما اعلام کنه، خودمون میتونیم پیام مربوط به خطا رو تعیین یا به دلخواه تنظیم کنیم. به شکل کد زیر:
catch(Exception ex)
{
Console.WriteLine("An error occured: " + ex.Message);
}
همونطور که میبینی، یک بخش جدید به ساختار دستوری try-catch اضافه کردیم. با استفاده از این کد میخوایم بفهمیم چه خطایی در برنامه اتفاق افتاده و در این مثال از کلاس اصلی خطاها، یعنی Exception استفاده کردیم. با اجرای کد بالا، اطلاعاتی درباره خطای رخداده به دست میاریم و با استفاده از خاصیت Message-Property میتونیم توضیحی قابل فهم درباره خطا مشاهده کنیم.
همونطور که گفتیم، Exception رایجترین نوع خطا هنگام اجرای برنامههای C# محسوب میشه. قوانین خطایابی در زبان سیشارپ به ما میگه بهتره همواره Exceptionهایی که احتمال رخ دادن اونها کمتره رو در کد خودمون استفاده کنیم. اما در مثال این درس، ما در اصل میدونستیم چه خطایی ممکنه در برنامه رخ بده. اما از کجا؟
دلیلش اینه که Visual Studio خطای مدیریتنشده رو به ما اعلام کرد. اما اگر درباره نوع خطا مطمئن نباشی، معمولاً شرح خطا یا Exception توسط برنامه نمایش داده میشه. راه دیگه برای پیدا کردن نوع خطا، استفاده از کلاس Exception Class هست. برای این کار، کد مثال قبل رو به شکل زیر تغییر بده:
Console.WriteLine("An error occured: " + ex.GetType().ToString());
نتیجه کد بالا، همونطور که میشه پیشبینی کرد، خطای "مقدار خارج از محدوده" یا Index Out Range Exception هست. ما باید این خطا رو مدیریت یا handle کنیم. البته میتونیم در یک زمان، بیشتر از یک نوع خطا رو هم در کد مدیریت کنیم و برای هر خطا، تصمیم مناسبی داشته باشیم. بنابراین کد مثال قبل رو به شکل زیر تغییر بده:
catch(IndexOutOfRangeException ex)
{
Console.WriteLine("An index was out of range!");
}
catch(Exception ex)
{
Console.WriteLine("Some sort of error occured: " + ex.Message);
}
همونطور که در کد بالا مشخص کردیم، برنامه ابتدا به دنبال خطاهای Index Out Range Exception میگرده. اگر از روش دوم برای خطایابی استفاده کنیم، ساختار Catch با استفاده از کلاس Exception Class میتونه مشکل کد رو پیدا کنه، چون تمام Exceptionها از این کلاس مشتق میشن. به عبارت دیگه، در خطایابی کدها باید همیشه خطایی که احتمال رخ دادن اون بیشتره رو در ابتدا قرار بدیم.
نکته دیگهای که باید درباره Exception Handling بدونی، بلوک کد نهایی یا finally block هست. بلوک finally رو میتونیم به انتهای ساختار دستوری try-catch اضافه کنیم یا در صورت نیاز، به صورت جداگانه از اون استفاده کنیم.
کدی که در بخش finally قرار میگیره در هر صورت اجرا میشه؛ چه Exception اتفاق بیفته و چه نیفته. به همین دلیل، finally محل مناسبی برای قرار دادن کدهایی مثل قطع ارتباط با فایلهای برنامه یا تخریب اشیاییه که دیگه به اونها نیازی نداریم. از اونجایی که مثالهای قبلی نسبتاً ساده بودن، به عملیات پاکسازی یا Clean up خاصی نیاز نداشتیم و Garbage Collector خودکار C# کارهای لازم رو انجام میداد.
اما در بعضی از کدهای گستردهتر، ممکنه به یک قطعه کد نهایی یا finally نیاز داشته باشیم. مثال زیر نحوه استفاده از این امکان رو به صورت عملی نشون میده:
int[] numbers = new int[2];
try
{
numbers[0] = 23;
numbers[1] = 32;
numbers[2] = 42;
foreach(int i in numbers)
Console.WriteLine(i);
}
catch(IndexOutOfRangeException ex)
{
Console.WriteLine("An index was out of range!");
}
catch(Exception ex)
{
Console.WriteLine("Some sort of error occured: " + ex.Message);
}
finally
{
Console.WriteLine("It's the end of our try block. Time to clean up!");
}
Console.ReadLine();
اگر کد مثال بالا رو اجرا کنی، میبینی که هم دستورات بخش خطا یا Exception و هم دستورات بخش نهایی یا finally code اجرا میشن. اگر خط کدی رو که عدد 42 رو به آرایه مثال اضافه میکنه حذف کنی، میبینی که فقط دستورات بخش finally اجرا میشن، چون دیگه خطایی در کد وجود نداره.
نکته مهم دیگهای که باید درباره Exceptionها بدونی، نحوه تأثیرگذاری خطاها روی متدها و توابعیه که Exception داخل اونها اتفاق میافته. همه خطاهای مدیریتنشده در برنامه لزوماً باعث از بین رفتن برنامه یا خروج کامل اون نمیشن. اما حتی وقتی یک خطا باعث توقف کامل برنامه نمیشه، نباید انتظار داشته باشی بقیه کد متد یا تابعی که Exception داخل اون اتفاق افتاده، اجرا بشه.
به عبارت دیگه، اگر Exception رو مدیریت کنی، کدهای بعد از بلوک دستوری try اجرا میشن، نه دستورات داخل خود اون. در مثال بالا، حلقهای که مقادیر آرایه array رو در خروجی چاپ میکنه، هیچوقت اجرا نمیشه، چون با رخ دادن Exception یا خطا در کد try، برنامه به اولین خط بعد از بلوک try و بخشهای Catch یا finally میره. اما خط آخر که در اون برای جلوگیری از خروج ویندوز از برنامه منتظر دریافت ورودی از کاربر هستیم، یعنی Console.ReadLine، همچنان اجرا میشه. بنابراین هنگام طراحی ساختارهای دستوری try-catch باید این نکته رو در نظر داشته باشی.
اگر میخوای مفاهیمی مثل Exception Handling، ساختارهای try-catch و کار با خطاها رو در کنار سایر مباحث زبان C# به شکل منظم و کاربردی یاد بگیری، میتونی مسیر یادگیریت رو با دوره آموزش C# ادامه بدی. این دوره میتونه قدم بعدی مناسبی برای عمیقتر شدن در برنامهنویسی با C# باشه.
بسیار عالی متشکرم