Så här kör du rensningskod med hjälp av slutligen
Syftet med en finally
instruktion är att säkerställa att den nödvändiga rensningen av objekt, vanligtvis objekt som innehåller externa resurser, sker omedelbart, även om ett undantag utlöses. Ett exempel på en sådan rensning är att anropa Close direkt FileStream efter användning i stället för att vänta på att objektet ska vara skräp som samlas in av den vanliga språkkörningen enligt följande:
static void CodeWithoutCleanup()
{
FileStream? file = null;
FileInfo fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
file.Close();
}
Exempel
Om du vill omvandla den tidigare koden till en try-catch-finally
-instruktion separeras rensningskoden från arbetskoden på följande sätt.
static void CodeWithCleanup()
{
FileStream? file = null;
FileInfo? fileInfo = null;
try
{
fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
}
finally
{
file?.Close();
}
}
Eftersom ett undantag kan inträffa när som helst inom try
blocket innan anropet OpenWrite()
, eller om själva anropet OpenWrite()
kan misslyckas, är vi inte garanterade att filen är öppen när vi försöker stänga den. Blocket finally
lägger till en kontroll för att kontrollera att FileStream objektet inte null
är innan du anropar Close metoden. null
Utan kontrollen finally
kan blocket utlösa sina egna NullReferenceException, men att utlösa undantag i finally
block bör undvikas om det är möjligt.
En databasanslutning är en annan bra kandidat för att stängas i ett finally
block. Eftersom antalet anslutningar som tillåts till en databasserver ibland är begränsat bör du stänga databasanslutningar så snabbt som möjligt. Om ett undantag utlöses innan du kan stänga anslutningen är det bättre att använda finally
blocket än att vänta på skräpinsamling.