In teoria, un blocco try / catch non avrà alcun effetto sul comportamento del codice a meno che non si verifichi effettivamente un'eccezione. Ci sono alcune rare circostanze, tuttavia, in cui l'esistenza di un blocco try / catch può avere un effetto maggiore, e alcune non comuni ma quasi oscure in cui l'effetto può essere evidente. La ragione di ciò è che quel codice dato come:
Action q;
double thing1()
{ double total; for (int i=0; i<1000000; i++) total+=1.0/i; return total;}
double thing2()
{ q=null; return 1.0;}
...
x=thing1(); // statement1
x=thing2(x); // statement2
doSomething(x); // statement3
il compilatore potrebbe essere in grado di ottimizzare statement1 in base al fatto che statement2 è garantito per essere eseguito prima di statement3. Se il compilatore è in grado di riconoscere che cosa1 non ha effetti collaterali e cosa2 in realtà non usa x, può tranquillamente omettere del tutto cosa1. Se [come in questo caso] cosa1 fosse costoso, questa potrebbe essere una grande ottimizzazione, anche se i casi in cui cosa1 è costoso sono anche quelli che il compilatore avrebbe meno probabilità di ottimizzare. Supponiamo che il codice sia stato modificato:
x=thing1(); // statement1
try
{ x=thing2(x); } // statement2
catch { q(); }
doSomething(x); // statement3
Ora esiste una sequenza di eventi in cui statement3 potrebbe essere eseguito senza aver eseguito statement2. Anche se nulla nel codice per thing2
potrebbe generare un'eccezione, sarebbe possibile che un altro thread potesse usare un Interlocked.CompareExchange
per notare che è q
stato cancellato e impostato su Thread.ResetAbort
, e quindi eseguire Thread.Abort()
un'istruzione before2 in cui ha scritto il suo valore x
. Quindi catch
eseguirà Thread.ResetAbort()
[tramite delegato q
], consentendo l'esecuzione per continuare con statement3. Una tale sequenza di eventi sarebbe ovviamente eccezionalmente improbabile, ma è necessario un compilatore per generare codice che funzioni secondo le specifiche anche quando si verificano tali eventi improbabili.
In generale, il compilatore ha molte più probabilità di notare opportunità di tralasciare semplici bit di codice rispetto a quelli complessi, e quindi sarebbe raro che un tentativo / cattura possa influire molto sulle prestazioni se non vengono mai generate eccezioni. Tuttavia, ci sono alcune situazioni in cui l'esistenza di un blocco try / catch potrebbe impedire ottimizzazioni che - ma per il tentativo / catch - avrebbero permesso al codice di funzionare più velocemente.