Undantag och prestanda
Kommentar
Det här innehållet skrivs om med behörighet från Pearson Education, Inc. från Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Den utgåvan publicerades 2008, och boken har sedan dess reviderats helt i den tredje utgåvan. En del av informationen på den här sidan kan vara inaktuell.
Ett vanligt problem med undantag är att om undantag används för kod som rutinmässigt misslyckas är implementeringens prestanda oacceptabel. Detta är ett verkligt problem. När en medlem utlöser ett undantag kan dess prestanda vara storleksordningar långsammare. Det är dock möjligt att uppnå bra prestanda samtidigt som man strikt följer undantagsriktlinjerna som inte tillåter användning av felkoder. Två mönster som beskrivs i det här avsnittet föreslår sätt att göra detta.
❌ Använd INTE felkoder på grund av problem med att undantag kan påverka prestanda negativt.
För att förbättra prestandan är det möjligt att använda antingen Testar-Doer-mönstret eller Try-Parse Pattern, som beskrivs i de kommande två avsnitten.
Testare-Doer-mönster
Ibland kan prestanda för en undantagsaktiv medlem förbättras genom att dela upp medlemmen i två. Nu ska vi titta på Add gränssnittets ICollection<T> metod.
ICollection<int> numbers = ...
numbers.Add(1);
Metoden Add
genererar om samlingen är skrivskyddad. Detta kan vara ett prestandaproblem i scenarier där metodanropet förväntas misslyckas ofta. Ett sätt att åtgärda problemet är att testa om samlingen kan skrivas innan du försöker lägga till ett värde.
ICollection<int> numbers = ...
...
if (!numbers.IsReadOnly)
{
numbers.Add(1);
}
Medlemmen som används för att testa ett villkor, som i vårt exempel är egenskapen IsReadOnly
, kallas testaren. Den medlem som används för att utföra en potentiellt utlösande åtgärd, Add
metoden i vårt exempel, kallas doer.
✔️ ÖVERVÄG Testar-Doer-mönstret för medlemmar som kan utlösa undantag i vanliga scenarier för att undvika prestandaproblem relaterade till undantag.
Prova parsningsmönster
För extremt prestandakänsliga API:er bör ett ännu snabbare mönster än testar-Doer-mönstret som beskrivs i föregående avsnitt användas. Mönstret kräver att medlemsnamnet justeras för att göra ett väldefinierat testfall till en del av medlemssemantiken. Definierar DateTime till exempel en Parse metod som utlöser ett undantag om parsningen av en sträng misslyckas. Den definierar också en motsvarande TryParse metod som försöker parsa, men returnerar false om parsning misslyckas och returnerar resultatet av en lyckad parsning med hjälp av en out
parameter.
public struct DateTime
{
public static DateTime Parse(string dateTime)
{
...
}
public static bool TryParse(string dateTime, out DateTime result)
{
...
}
}
När du använder det här mönstret är det viktigt att definiera try-funktionen i strikta termer. Om medlemmen misslyckas av någon annan anledning än det väldefinierade försöket måste medlemmen fortfarande utlösa ett motsvarande undantag.
✔️ ÖVERVÄG Try-Parse-mönstret för medlemmar som kan utlösa undantag i vanliga scenarier för att undvika prestandaproblem relaterade till undantag.
✔️ Använd prefixet "Try" och boolesk returtyp för metoder som implementerar det här mönstret.
✔️ Ange en undantagsbesparande medlem för varje medlem med hjälp av Try-Parse-mönstret.
Portioner © 2005, 2009 Microsoft Corporation. Med ensamrätt.
Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, publicerad 22 okt 2008 av Addison-Wesley Professional som en del av Microsoft Windows Development Series.