Em teoria, um bloco try / catch não terá efeito no comportamento do código, a menos que uma exceção realmente ocorra. Existem algumas circunstâncias raras, no entanto, em que a existência de um bloco de tentativa / captura pode ter um efeito importante, e outras incomuns, mas dificilmente obscuras, nas quais o efeito pode ser perceptível. A razão para isso é que o código fornecido, como:
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
o compilador pode otimizar a instrução1 com base no fato de que a instrução2 é executada antes da instrução3. Se o compilador puder reconhecer que o item1 não tem efeitos colaterais e o item2 não usa x, ele pode omitir completamente o item1. Se [como neste caso] a coisa1 for cara, isso pode ser uma grande otimização, embora os casos em que a coisa1 seja cara também sejam aqueles em que o compilador provavelmente menos otimizará. Suponha que o código tenha sido alterado:
x=thing1(); // statement1
try
{ x=thing2(x); } // statement2
catch { q(); }
doSomething(x); // statement3
Agora existe uma sequência de eventos em que a instrução3 poderia ser executada sem a instrução2 ter sido executada. Mesmo que nada no código for thing2
capaz de gerar uma exceção, seria possível que outro thread pudesse usar um Interlocked.CompareExchange
para perceber que q
foi limpo e configurá-lo como Thread.ResetAbort
, e então executar uma Thread.Abort()
instrução before2 que escreveu seu valor em x
. Então o catch
seria executado Thread.ResetAbort()
[via delegado q
], permitindo que a execução continuasse com a instrução3. É claro que essa sequência de eventos seria excepcionalmente improvável, mas é necessário um compilador para gerar código que funcione de acordo com as especificações, mesmo quando esses eventos improváveis ocorrem.
Em geral, é muito mais provável que o compilador perceba oportunidades de deixar de fora pedaços simples de código que códigos complexos e, portanto, seria raro uma tentativa / captura afetar o desempenho muito se exceções nunca forem lançadas. Ainda assim, existem algumas situações em que a existência de um bloco try / catch pode impedir otimizações que - mas para o try / catch - teriam permitido que o código fosse executado mais rapidamente.