C# - Hibakezelés a C#-ban

C# nyelv 7. rész

forráskód letöltése
Ebben a cikkben a C# hibakezelési lehetőségeivel ismerkedünk meg részletesebben.
A melléklet példában látható Form-ra felhelyeztünk néhány nyomógombot. Mindegyik lenyomásakor egy-egy hibát generáltatunk oly módon, hogy nullával próbálunk meg osztani.
Ahogy az az első nyomógombnál lévő példánál látható, az esetlegesen problémás forráskód sorainkat célszerű egy try kulcsszó után írt kapcsos zárójel közé helyezni. Ennek hatására, ha az itt közrezárt forráskódjainkban bármi hiba történne (mint ahogy most lesz is a nullával történő osztály miatt), akkor ennek lekezelését mi magunk végezhetjük el. Ehhez egy catch kulcsszó használatára lesz szükségünk. Az itt megadott forráskód sorok csak akkor futnak le, ha try soraiban hiba keletkezik.
     protected void button1_Click (object sender, System.EventArgs e)
      {
        int a;
        int b;
        int c;
        try
        {
          a = 10;
          b = 0;
          c = a / b;
        }
        catch
        {
          MessageBox.Show("hiba");
        }
      }
A második nyomógombnál már nem csak ellenőrizzük, hogy történt-e a hiba, hanem megpróbáljuk a hiba jellegére utaló információkat meg is jeleníteni. Ehhez szükségünk lesz egy új osztály használatára, mely az Exception lesz. Ebből a catch-nél hozhatunk létre egy változót, melyet felhasználva különféle információkat tudunk meg a bekövetkezett hiba jellegéről. Ha minden információt egyetlen sztringként szeretnénk megjeleníteni, akkor használhatjuk a ToString függvényét az osztálynak.
      protected void button2_Click (object sender, System.EventArgs e)
      {
        int a;
        int b;
        int c;
        try
        {
          a = 10;
          b = 0;
          c = a / b;
        }
        catch (Exception ex)
        {
          MessageBox.Show(ex.ToString());
        }
       }
Ha a bekövetkezett hiba egyes tulajdonságait nem egyetlen sztringként szeretnénk viszontlátni, akkor természetesen ez is megoldható az Exception osztály property-einek használatával. A harmadik nyomógombnál erre láthatunk példát. Itt egy ListBox komponensbe soroljuk fel a legfontosabb tulajdonságait a bekövetkezett hibának. Így például a Message property-n keresztül tudhatjuk meg a létrejött hiba szöveges leírását. A StackTrace property arról árulkodik, hogy melyik függvényünkben jött létre a hiba és hogy ezt melyik forráskódunk, melyik sorában találjuk. A GetType-on keresztül megtudhatjuk azt az osztályt, mely a létrejött hibát képviseli. Nullával osztás esetén ez a DivideByZeroException osztály lesz.
      protected void button3_Click (object sender, System.EventArgs e)
      {
        int a;
        int b;
        int c;
        try
        {
          a = 10;
          b = 0;
          c = a / b;
        }
        catch (Exception ex)
        {
          listBox1.Items.Add("Message: "+ex.Message); 
          listBox1.Items.Add("StackTrace: "+ex.StackTrace); 
          listBox1.Items.Add("TargetSite: "+ex.TargetSite); 
          listBox1.Items.Add("GetType: "+ex.GetType().ToString());
        }
      }
A hibakezelésnél lehetőségünk van arra is, hogy a hiba jellegétől függően elágaztassuk a programunk futását a hibakezelő résznél. Ehhez csak arra van szükségünk, hogy több catch kulcsszót használjunk, ahogy ez a negyedik nyomógombnál is látható. Itt minden catch-nél egy-egy a hibára jellemző osztályt kell megadni. A nullával való osztás ellenőrzéséhez a DivideByZeroException tartozik, mely az Exception osztályból származik, mint minden más hibakezelő osztály. A másik catch-nél megadtuk az Exception osztályt. Ezzel azt érjük el, hogy a try kulcsszó után megadott program soroknál, ha hiba történik és ez nullával való osztás lesz, akkor az első catch után folytatódik a program futása. Ha nem nullával való osztási hiba jön létre, akkor a második catch után folytatódna a program, mivel az Exception minden egyéb hibát kezel.
      protected void button4_Click (object sender, System.EventArgs e)
      {
        int a;
        int b;
        int c;
        try
        {
          a = 10;
          b = 0;
          c = a / b;
        }
        catch (DivideByZeroException ex)
        {
          MessageBox.Show("DivideByZeroException hiba: " + ex.Message.ToString());
        }
        catch (Exception ex)
        {
          MessageBox.Show("Általános hiba: " + ex.Message.ToString());
        }
      }
Az utolsó nyomógombnál nem csak a felmerülő hiba kezelését valósítjuk meg, hanem ennél többre is szükségünk van. Azokban az esetekben amikor egy olyan folyamatot kezdeményezünk, melyet minden esetben le is kell zárnunk, akkor nem elegendő a try és catch használata. Például, ha megnyitunk egy állományt, majd különféle műveleteket végzünk, akkor ezek után az állományt le is kell zárnunk. Ha viszont hiba történik az állomány nyitása és zárása közötti részen, akkor már nem fut le a programkód, mely az állományunkat bezárná. Ekkor lesz szükségünk finally kulcsszó használatára. Az ezután megadott kódrészlet minden esetben le fog futni, akkor is ha történik hiba és akkor is ha nem. Míg a catch után megadott kód csak hiba esetén fut, így itt nem rendelkezhetnénk az állomány lezárásáról.
      protected void button5_Click (object sender, System.EventArgs e)
      {
        int a;
        int b;
        int c;
        Stream st = File.Open(Application.StartupPath + "\\tmp.txt", FileMode.OpenOrCreate);
        try
        {
          a = 10;
          b = 0;
          c = a / b;          
        }
        catch
        {
          MessageBox.Show("hiba");
        }
        finally
        {
          st.Close();
        }        
      }

C# nyelv cikksorozat