Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I C# sprids fel i programmet vid körning genom programmet med hjälp av en mekanism som kallas undantag. Undantag utlöses av kod som påträffar ett fel och fångas av kod som kan korrigera felet. Undantag kan genereras av .NET-körningen eller av kod i ett program. När ett undantag har genererats sprids anropsstacken tills en catch
instruktion för undantaget hittas. Ohanterade undantag hanteras av en allmän undantagshanterare som tillhandahålls av systemet som visar en dialogruta.
Undantag representeras av klasser som härletts från Exception. Den här klassen identifierar typen av undantag och innehåller egenskaper som innehåller information om undantaget. Att utlösa ett undantag innebär att skapa en instans av en undantagsbaserad klass, eventuellt konfigurera egenskaper för undantaget och sedan generera objektet med hjälp av nyckelordet throw
. Till exempel:
class CustomException : Exception
{
public CustomException(string message)
{
}
}
private static void TestThrow()
{
throw new CustomException("Custom exception in TestThrow()");
}
När ett undantag kastas kontrollerar körningstidsmiljön den aktuella instruktionen för att se om den är inom ett try
-block. I så fall kontrolleras alla catch
block som är associerade med try
blocket för att se om de kan fånga undantaget.
Catch
block anger vanligtvis undantagstyper. Om blocktypen catch
är av samma typ som undantaget, eller en basklass för undantaget, catch
kan blocket hantera metoden. Till exempel:
try
{
TestThrow();
}
catch (CustomException ex)
{
System.Console.WriteLine(ex.ToString());
}
Om satsen som utlöser ett undantag inte finns i ett try
-block eller om try
-blocket som omsluter det inte har något matchande catch
-block, kontrollerar körningen den anropande metodens try
-sats och catch
-block. Körningen fortsätter upp i den anropande stacken och söker efter ett kompatibelt catch
block. När blocket catch
har hittats och körts skickas kontrollen till nästa instruktion efter det catch
blocket.
En try
instruktion kan innehålla mer än ett catch
block. Den första catch
instruktionen som kan hantera undantaget körs. Följande catch
instruktioner, även om de är kompatibla, ignoreras. Sortera fångstblock från de mest specifika (eller mest härledda) till minst specifika. Till exempel:
using System;
using System.IO;
namespace Exceptions
{
public class CatchOrder
{
public static void Main()
{
try
{
using (var sw = new StreamWriter("./test.txt"))
{
sw.WriteLine("Hello");
}
}
// Put the more specific exceptions first.
catch (DirectoryNotFoundException ex)
{
Console.WriteLine(ex);
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex);
}
// Put the least specific exception last.
catch (IOException ex)
{
Console.WriteLine(ex);
}
Console.WriteLine("Done");
}
}
}
Innan catch
blocket körs, kontrollerar körningen efter finally
block.
Finally
block gör det möjligt för programmeraren att rensa alla tvetydiga tillstånd, som kan lämnas över från ett avbrutet try
block, eller frigöra externa resurser (till exempel grafikhandtag, databasanslutningar eller filströmmar) utan att behöva vänta på att sopinsamlaren i körningen ska slutföra objekten. Till exempel:
static void TestFinally()
{
FileStream? file = null;
//Change the path to something that works on your machine.
FileInfo fileInfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Closing the file allows you to reopen it immediately - otherwise IOException is thrown.
file?.Close();
}
try
{
file = fileInfo.OpenWrite();
Console.WriteLine("OpenWrite() succeeded");
}
catch (IOException)
{
Console.WriteLine("OpenWrite() failed");
}
}
Om WriteByte()
utlöser ett undantag kommer koden i det andra try
-blocket som försöker öppna filen igen att misslyckas om file.Close()
inte kallas, och filen kommer förbli låst. Eftersom finally
block körs även om ett undantag utlöses tillåter finally
blocket i föregående exempel att filen stängs korrekt och hjälper till att undvika ett fel.
Om inget kompatibelt catch
block hittas i anropsstacken efter att ett undantag har genererats inträffar en av tre saker:
- Om undantaget finns inom en finalator avbryts finalatorn och den eventuella basfinalatorn anropas.
- Om anropsstacken innehåller en statisk konstruktor eller en initiator för statiska fält, kastas ett TypeInitializationException, där det ursprungliga undantaget tilldelas InnerException egenskapen för det nya undantaget.
- Om trådstarten har nåtts avslutas tråden.