16/04/20151 Výjimky a zpracování chyb (1) Výjimky (exceptions) dovolují tvorbu progra- mů, které mohou reagovat na různé chybové stavy vzniklé v jeho průběhu Cílem výjimek je učinit programy robustnější tím, že jsou rozšířeny o schopnosti správy chyb vzniklých na úrovni aplikace nebo operačního systému Výjimky v jazyku C#: –jsou objektově orientované –oddělují zpracování chyb od výkonného kódu –nejsou hlídané (checked) –by měly být dokumentovány v XML
16/04/20152 Výjimky a zpracování chyb (2) Každá výjimka v jazyku C# je: –objekt –odvozena z třídy Exception nebo z některé z je- jich následníků –obsahuje informace o: svém původu důvodu vzniku Pomocí zachycení výjimky je možné nastalý (chybový) stav zpracovat (obsloužit) Jestliže dojde ke vzniku výjimky, která není ni- jak obsloužena, pak dochází k ukončení progra- mu s odpovídající běhovou chybou
16/04/20153 Třída Exception (1) Definována ve jmenném prostoru System Reprezentuje chyby, ke kterým dochází v době běhu programu Slouží jako výchozí třída pro všechny další vý- jimky Definuje např. vlastnosti: –Message : vrací řetězec (text) popisující vzniklou výjimku je nastavena jako parametr konstruktoru –Source : vrací nebo nastavuje jméno aplikace nebo objektu, který výjimku vyvolal
16/04/20154 Třída Exception (2) –StackTrace : vrací stav zásobníku v době vzniku výjimky posloupnost metod, které vedly k vyvolání výjimky příklad (zaformátováno): at Excep.Program.Div(Int32 a, Int32 b) in c:\Excep\Excep\Program.cs:line 17 at Excep.Program.Main(String[] args) in c:\Excep\Excep\Program.cs:line 27 poznámka: program musí být přeložený v režimu debug –HelpLink : vrací nebo nastavuje URL na soubor popisující chybu –InnerException : obsahuje informace o předcházející výjimce, která způso- bila současnou výjimku předcházející výjimka je zaznamenána předáním (jako pa- rametr) konstruktoru současné výjimky
16/04/20155 Rozdělení výjimek Výjimky v.NET Frameworku byly původně roz- dělovány do dvou skupin, jimž odpovídají třídy (potomci třídy Exception ): –SystemException : pro výjimky CLR (Common Language Runtime), tj. pro běhové prostředí (součást.NET Frameworku), které se sta- rá o spouštění programů, správu paměti, typovou bezpeč- nost nebo o výjimky –ApplicationException : pro výjimky uživatelských aplikací Zmíněné: –rozdělení dnes často není dodržováno ani v BCL –třídy zůstávají zachovány pro zpětnou kompatibiltu
16/04/20156 Typy výjimek (1) Třídy reprezentující výjimky pro parametry: –ArgumentException : potomek třídy SystemException byl předán parametr s neplatnou hodnotou pomocí vlastnosti ParamName lze zjistit jméno paramet- ru, který tuto výjimku způsobuje –ArgumentNullException : potomek třídy ArgumentException metodě byl předán parametr s hodnotou null, přičemž tato metoda jej neakceptuje jako platný parametr –ArgumentOutOfRangeException : potomek třídy ArgumentException hodnota parametru je mimo povolený rozsah
16/04/20157 Typy výjimek (2) Třídy pro aritmetické výjimky: –ArithmeticException : potomek třídy SystemException nastala chyba při aritmetické operaci nebo při převodu –DivideByZeroException : potomek třídy ArithmeticException došlo k dělení nulou –OverflowException : potomek třídy ArithmeticException aritmetická operace nebo převod skončil přetečením vý- sledku
16/04/20158 Typy výjimek (3) vznik přetečení není standardně hlídán hlídání přetečení lze zapnout, resp. vypnout –v nastavení projektu –pomocí klíčových slov checked, resp. unchecked –příklad: int x = int.MaxValue; checked { x++; //vyvolá výjimku OverflowException } int x = int.MaxValue; unchecked { x++; //nevyvolá výjimku OverflowException }
16/04/20159 Typy výjimek (4) Třídy pro výjimky při provádění I/O operací (de- finovány ve jmenném prostoru System.IO ): –IOException : potomek třídy SystemException bázová třída pro chyby při zpracování vstupu a výstupu –FileNotFoundException : potomek třídy IOException vzniká při pokusu o zpřístupnění neexistujícího souboru –PathTooLongException : potomek třídy IOException dochází k ní jestliže cesta nebo název souboru je delší než systémem definované maximum
16/04/ Typy výjimek (5) Další třídy reprezentující výjimky (odvozeny od třídy SystemException ): –InvalidOperationException : metodu není možné spustit, protože objekt není ve valid- ním stavu například zápis do proudu, který ještě nebyl otevřen –FormatException : formát vstupu neodpovídá požadavkům příklad: int.Parse("Program") může být vyvolána i např. v případě čtení ze souboru nebo zařízení –IndexOutOfRangeException : pokus o manipulaci v poli s prvkem, jehož index je mimo rozsah pole
16/04/ Typy výjimek (6) –NullReferenceException : pokus se o dereferencování objektu, který je null například pokus o vyvolání jeho metody aplikace by neměla tuto výjimku vyvolávat –InvalidCastException : vzniká při pokusu o neplatné přetypování příklad: (int) "Program" aplikace by neměla tuto výjimku vyvolávat –OutOfMemoryException : není dostatek paměti pro pokračování programu aplikace by neměla tuto výjimku vyvolávat ani zachytávat
16/04/ Typy výjimek (7) –StackOverflowException : došlo k přetečení prováděcího zásobníku (obvykle příliš mnoho volaných metod) aplikace by neměla tuto výjimku vyvolávat ani zachytávat příklad: public string BadProperty { get { return badProperty; } set //StackOverflowException { BadProperty = value; } }
16/04/ Práce s výjimkami (1) Nově vytvářená výjimka (třída reprezentující výjimku) by měla: –být odvozena od třídy Exception nebo od nějaké- ho následníka třídy Exception –implementovat alespoň 4 základní konstruktory jako třída Exception Konvence: –název výjimky končí slovem Exception Bývá vhodné přidat vlastnosti pro další infor- mace: –není vhodné předávat všechny důležité informace jen pomocí vlastnosti Message
16/04/ Práce s výjimkami (2) Výjimky by měly být používány jen pro výji- mečné stavy: –zpracování výjimky je náročnější než použití podmí- něného příkazu –jestliže lze chybu očekávat často, je lepší ji řešit pro- gramově (pomocí podmíněného příkazu nebo návra- tové hodnoty) Nikdy by: –neměla být vyvolávána výjimka přímo třídy Exception –neměl být použitý prázdný blok catch –normální užívání třídy nemělo způsobit výjimku
16/04/ Práce s výjimkami (3) Výjimka může být v programu vyvolána pomo- cí klíčového slova throw Blok catch, který danou výjimku zachytí, mů- že přidat další doplňující informace a provést je- jí opětovné vyvolání Příklad: try {... } catch (Exception ex) {... throw; }
16/04/ Práce s výjimkami (4) nebo: try {... } catch (Exception ex) {... throw ex; } Je-li při opětovném vyvolání výjimky použita proměnná, jež výjimku reprezentuje, dojde k re- setování zásobníku (stack trace), v němž jsou uchovávány informace o vzniklých výjimkách
16/04/ Třídy Trace a Debug (1) Definovány ve jmenném prostoru System.Diagnostics Slouží k zápisu: –trasovacích informací – třída Trace : podávají informace o průběhu aplikace –ladících informací – třída Debug : obvykle podávají zprávy o „výjimečných“ událostech, které v aplikaci nastaly Umožňují definovat, aby určité informace byly zapisovány pouze v případě splnění nějaké pod- mínky
16/04/ Třídy Trace a Debug (2) Informace, které budou podávány v průběhu aplikace závisí na způsobu jejího překladu Jestliže je aplikace přeložena s definovanou konstantou (pomocí direktivy preprocesoru): –DEBUG ( #define DEBUG ): jsou podávány ladící informace –TRACE ( #define TRACE ): jsou podávány trasovací informace Poznámka: –skutečnost, zda konstanty DEBUG a TRACE budou v době překladu definovány (či nikoliv) lze nastavit i pomocí menu prostředí MS Visual Studio (Project Properties karta Build)
16/04/ Třídy Trace a Debug (3) Prostředí MS Visual Studio umožňuje aplikaci přeložit v režimu: –Debug: režim, v němž je standardně definována konstanta DEBUG i konstanta TRACE –Release: režim, v němž je standardně definována pouze konstanta TRACE Zápis trasovacích a ladících informací je reali- zován pomocí tzv. posluchačů (listeners), ulože- ných v kolekci (reprezentovanou vlastností): –Trace.Listeners –Debug.Listeners
16/04/ Třídy Trace a Debug (4) V roli posluchačů mohou být použity např. třídy: –TextWriterTraceListener : zapisuje do textového proudu –EventLogTraceListener : zapisuje do deníku událostí Windows –ConsoleTraceListener : zapisuje do konzole –DefaultTraceListener : posílá zprávy pomocí Windows API debuggeru –DelimitedListTraceListener : zapisuje do souboru –XmlWriterTraceListener : zapisuje do XML souboru
16/04/ Třídy Trace a Debug (5) Třídy Trace a Debug mimo jiné definují me- tody: –Write : zapisuje zprávu –WriteLine : zapisuje zprávu a symbol konce řádku –WriteIf : zapisuje zprávu v případě, že je splněna zadaná podmínka –WriteLineIf : podobně jako WriteIf, navíc zapíše symbol konce řádku –Fail : zobrazí chybové okno se správou (v kolekci posluchačů musí být použitý DefaultTraceListener )
16/04/ Třídy Trace a Debug (6) –Assert : v případě, že není splněna zadaná podmínka, zobrazuje okno s výpisem obsahu zásobníku volání –Indent : zvětší úroveň odsazení o počet mezer specifikovaných vlastností IndentSize –Unindent : zmenší úroveň odsazení –Flush : vyprázdní výstupní vyrovnávací paměť a způsobuje, že data jsou zapsána do posluchačů poznámka: –je-li nastavena vlastnost AutoFlush na hodnotu true, pak jsou data zapisována do posluchačů automaticky po každém zápisu
16/04/ Třídy Trace a Debug (7) Pro řízení trasování (ladění) lze používat přepí- nače (trace switches), reprezentované třídami: –BooleanSwitch : slouží k zapnutí (vypnutí) výpisu trasovacích a ladících zpráv –TraceSwitch : poskytuje pět úrovní ( Off, Error, Warning, Info, Verbose ) pro řízení výpisu trasovacích a ladících zpráv Nastavení přepínačů může být provedeno i modi- fikací konfiguračního souboru ( app.config )