Uitzonderingen en het verwerkingsproces voor uitzonderingen onderzoeken
- 11 minuten
Runtimefouten in een C#-toepassing worden beheerd met behulp van een mechanisme dat uitzonderingen wordt genoemd. Uitzonderingen bieden een gestructureerde, uniforme en typeveilige manier om foutvoorwaarden op systeemniveau en toepassingsniveau te verwerken. Uitzonderingen worden gegenereerd door de .NET-runtime of door de code in een toepassing.
Veelvoorkomende scenario's waarvoor uitzonderingsafhandeling is vereist
Er zijn verschillende programmeerscenario's waarvoor uitzonderingsafhandeling is vereist. Veel van deze scenario's hebben betrekking op een vorm van gegevensverwerving. Hoewel sommige scenario's betrekking hebben op coderingstechnieken die buiten het bereik van deze training vallen, zijn ze nog steeds de moeite waard om te noteren.
Veelvoorkomende scenario's waarvoor uitzonderingsafhandeling is vereist, zijn:
Gebruikersinvoer: Uitzonderingen kunnen optreden wanneer gebruikersinvoer door code wordt verwerkt. Uitzonderingen treden bijvoorbeeld op wanneer de invoerwaarde de verkeerde indeling of buiten het bereik heeft.
Gegevensverwerking en berekeningen: Uitzonderingen kunnen optreden wanneer code gegevensberekeningen of conversies uitvoert. Uitzonderingen treden bijvoorbeeld op wanneer de code probeert te delen door nul, casten naar een niet-ondersteund type, of een waarde toewijst die buiten het toegestane bereik ligt.
Bewerkingen voor bestandsinvoer/uitvoer: uitzonderingen kunnen optreden wanneer code wordt gelezen van of naar een bestand wordt geschreven. Er treden bijvoorbeeld uitzonderingen op wanneer het bestand niet bestaat, het programma heeft geen toegang tot het bestand of het bestand wordt gebruikt door een ander proces.
Databasebewerkingen: uitzonderingen kunnen optreden wanneer code communiceert met een database. Uitzonderingen treden bijvoorbeeld op wanneer de databaseverbinding is verbroken, er treedt een syntaxisfout op in een SQL-instructie of treedt een schending van de beperking op.
Netwerkcommunicatie: uitzonderingen kunnen optreden wanneer code communiceert via een netwerk. Er treden bijvoorbeeld uitzonderingen op wanneer de netwerkverbinding is verbroken, er een time-out optreedt of de externe server retourneert een fout.
Andere externe resources: uitzonderingen kunnen optreden wanneer code communiceert met andere externe resources. Webservices, REST API's of bibliotheken van derden kunnen om verschillende redenen uitzonderingen genereren. Uitzonderingen treden bijvoorbeeld op als gevolg van problemen met netwerkverbindingen, onjuiste gegevens, enzovoort.
Uitzonderingsafhandeling van trefwoorden, codeblokken en patronen
Afhandeling van uitzonderingen in C# wordt geïmplementeerd met behulp van de try, catchen finally trefwoorden. Elk van deze trefwoorden heeft een gekoppeld codeblok en kan worden gebruikt om te voldoen aan een specifiek doel in uw benadering van de verwerking van uitzonderingen. Voorbeeld:
try
{
// try code block - code that may generate an exception
}
catch
{
// catch code block - code to handle an exception
}
finally
{
// finally code block - code to clean up resources
}
Opmerking
Met de C#-taal kan uw code ook een uitzonderingsobject genereren met behulp van het throw trefwoord. Scenario's voor het verwerken van uitzonderingen die het gebruik van het trefwoord voor het throw genereren van uitzonderingen omvatten, worden behandeld in een afzonderlijke module in Microsoft Learn.
Het try codeblok bevat de beveiligde code die een uitzondering kan veroorzaken. Als de code in een try blok een uitzondering veroorzaakt, wordt de uitzondering verwerkt door een bijbehorend catch blok.
Het catch codeblok bevat de code die wordt uitgevoerd wanneer een uitzondering wordt opgevangen. Het catch blok kan de uitzondering verwerken, deze registreren of negeren. Een catch blok kan worden geconfigureerd om uit te voeren wanneer er een uitzonderingstype optreedt of alleen wanneer een specifiek type uitzondering optreedt.
Het finally codeblok bevat code die wordt uitgevoerd of er een uitzondering optreedt of niet. Het finally blok wordt vaak gebruikt om resources op te ruimen die in een try blok zijn toegewezen. Zorg er bijvoorbeeld voor dat aan een variabele de juiste of vereiste waarde is toegewezen.
Afhandeling van uitzonderingen in een C#-toepassing wordt over het algemeen geïmplementeerd met behulp van een of meer van de volgende patronen:
- Het
try-catchpatroon bestaat uit eentryblok gevolgd door een of meercatchcomponenten. Elkcatchblok wordt gebruikt om handlers op te geven voor verschillende uitzonderingen. - Het
try-finallypatroon bestaat uit eentryblok gevolgd door eenfinallyblok. Normaal gesproken worden de instructies van eenfinallyblok uitgevoerd wanneer de controle eentryinstructie verlaat. - Met het
try-catch-finallypatroon worden alle drie de typen uitzonderingsafhandelingsblokken geïmplementeerd. Een veelvoorkomend scenario voor hettry-catch-finallypatroon is wanneer resources worden verkregen en gebruikt in eentryblok, uitzonderlijke omstandigheden worden beheerd in eencatchblok en de resources worden vrijgegeven of anderszins beheerd in hetfinallyblok.
Hoe worden uitzonderingen weergegeven in code?
Uitzonderingen worden in code weergegeven als objecten, wat betekent dat ze een exemplaar van een klasse zijn. De .NET-klassebibliotheek biedt uitzonderingsklassen die in code worden geopend, net als andere .NET-klassen. Een ander voorbeeld van .NET-klasse die wordt gebruikt als object in code, is de Random klasse (gebruikt om willekeurige getallen te maken).
Om precies te zijn, zijn uitzonderingen typen, vertegenwoordigd door klassen die uiteindelijk allemaal zijn afgeleid van System.Exception. Een uitzonderingsklasse die is afgeleid van Exception informatie die het type uitzondering aangeeft en eigenschappen bevat die details over de uitzondering bieden. Verderop in deze module wordt een uitgebreider onderzoek van de Exception klas opgenomen.
Een runtime-exemplaar van een klasse wordt meestal aangeduid als een object, dus uitzonderingen worden vaak uitzonderingsobjecten genoemd.
Opmerking
Hoewel ze soms door elkaar worden gebruikt, zijn een klasse en een object verschillende dingen. Een klasse definieert een type object, maar het is geen object zelf. Een object is een concrete entiteit op basis van een klasse.
Verwerkingsproces voor uitzonderingen
Wanneer er een uitzondering optreedt, zoekt de .NET-runtime naar de dichtstbijzijnde catch component die de uitzondering kan verwerken. Het proces begint met de methode die de uitzondering veroorzaakte. Eerst wordt de methode onderzocht om te zien of de code die de uitzondering heeft veroorzaakt zich in een try codeblok bevindt. Als de code zich in het try codeblok bevindt, worden de catch clausules die aan de try statement zijn gekoppeld in volgorde beschouwd. Als de catch clausules de uitzondering niet kunnen verwerken, wordt de methode die de huidige methode heeft aangeroepen, doorzocht. Deze methode wordt onderzocht om te bepalen of de methode-aanroep (naar de eerste methode) zich in een try codeblok bevindt. Als de aanroep zich in een try codeblok bevindt, worden de bijbehorende catch componenten overwogen. Dit zoekproces wordt voortgezet totdat een catch component wordt gevonden die de huidige uitzondering kan verwerken.
Zodra een catch component is gevonden die de uitzondering kan verwerken, bereidt de runtime zich voor om het besturingselement over te dragen naar de eerste instructie van het catch blok. Voordat het catch blok wordt uitgevoerd, voert de runtime echter alle finally blokken uit die zijn gekoppeld aan try instructies die tijdens de zoekopdracht zijn gevonden. Als er meer dan één finally blok wordt gevonden, worden deze op volgorde uitgevoerd, te beginnen met het blok dat het dichtst bij de code ligt waardoor de uitzondering werd gegenereerd.
Als er geen catch component wordt gevonden om de uitzondering af te handelen, beëindigt de runtime de toepassing en wordt er een foutbericht weergegeven aan de gebruiker.
Bekijk het volgende codevoorbeeld dat een try-finally patroon bevat dat is genest in een try-catch patroon:
try
{
// Step 1: code execution begins
try
{
// Step 2: an exception occurs here
}
finally
{
// Step 4: the system executes the finally code block associated with the try statement where the exception occurred
}
}
catch // Step 3: the system finds a catch clause that can handle the exception
{
// Step 5: the system transfers control to the first line of the catch code block
}
In dit voorbeeld vindt het volgende proces plaats:
- De uitvoering begint in het codeblok van de outer-instructie
try. - Er wordt een uitzondering gegenereerd in het codeblok van de interne
tryinstructie. - De runtime zoekt de
catchclausule die is gekoppeld aan de buitenste instructietry. - Voordat de runtime de controle overdraagt naar de eerste regel van het
catchcodeblok, wordt definallyclause uitgevoerd die hoort bij de internetryinstructie. - De runtime draagt vervolgens het besturingselement over naar de eerste regel van het
catchcodeblok en voert de code uit die de uitzondering afhandelt.
In dit eenvoudige voorbeeld bevinden de geneste try-catch en try-finally patronen zich binnen één methode, maar meerdere try-catch en try-finally patronen kunnen worden verspreid tussen methoden die andere methoden aanroepen.
Afhandelen van uitzonderingen en de oproepstack
U ziet vaak de term 'oproepstack-ontwinding' wanneer u leest over uitzonderingafhandeling en het proces van uitzonderingafhandeling. Als u deze term wilt begrijpen, moet u de aanroepstack begrijpen en hoe deze wordt gebruikt om de 'stack' van methode-aanroepen bij te houden tijdens het uitvoeren van code.
U kunt de oproepstack zien als een toren met blokken. Wanneer je een toren bouwt, begin je met slechts één blok. Telkens wanneer u een blok aan de toren toevoegt, plaatst u het op de bestaande blokken. Wanneer uw toepassing wordt uitgevoerd in het foutopsporingsprogramma, is het toegangspunt voor uw toepassing de eerste laag die is toegevoegd aan de aanroepstack (het eerste blok van de toren). Telkens wanneer een methode een andere methode aanroept, wordt de nieuwe methode toegevoegd aan de bovenkant van de stack. Wanneer uw code uit een methode wordt afgesloten, wordt de methode verwijderd uit de aanroepstack.
Opmerking
Voor een consoletoepassing is het toegangspunt voor uw toepassing de instructies op het hoogste niveau. In de aanroepstack van Visual Studio Code wordt dit toegangspunt de Main methode genoemd.
Het afwikkelen van aanroepstacks is het proces dat door de .NET-runtime wordt gebruikt wanneer een C#-programma een fout tegenkomt. Het is hetzelfde proces dat u zojuist hebt bekeken.
Als u terugkeert naar de bloktoren analogie, wanneer u een blok van de toren moet verwijderen, begint u vanaf de bovenkant en verwijdert u elk blok totdat u het blok bereikt dat u nodig hebt. Dit proces is vergelijkbaar met hoe het afwikkelen van een aanroepstack werkt, waarbij elke laag in de stack lijkt op een blok in een toren. Wanneer de runtime de call stack moet terugdraaien, begint deze vanuit de top en verwijdert iedere laag totdat het de laag bereikt die benodigd is. In dit geval is de aanroeplaag die nodig is de methode met een catch component die de uitzondering kan verwerken die is opgetreden.
Samenvatting
Hier volgen enkele belangrijke dingen die u in deze les moet onthouden:
- Veelvoorkomende scenario's waarvoor uitzonderingsafhandeling nodig kan zijn, zijn gebruikersinvoer, gegevensverwerking, I/O-bewerkingen van bestanden, databasebewerkingen en netwerkcommunicatie.
- Afhandeling van uitzonderingen in C# wordt geïmplementeerd met behulp van
try,catchenfinallytrefwoorden. Elk trefwoord heeft een gekoppeld codeblok dat een specifiek doel dient. - Uitzonderingen worden weergegeven als typen en afgeleid van de
System.Exceptionklasse in .NET. Uitzonderingen bevatten informatie die het type uitzondering aangeeft en eigenschappen die aanvullende informatie bieden. - Wanneer er een uitzondering optreedt, zoekt de .NET-runtime naar de dichtstbijzijnde
catchcomponent die deze kan verwerken. De zoekopdracht begint met de methode waarin de uitzondering is opgetreden en verplaatst zo nodig de aanroepstack omlaag.
Uw kennis controleren
Feedback
Is deze pagina nuttig?
Nee
Need help with this topic?
Want to try using Ask Learn to clarify or guide you through this topic?