Acabei de aprender que o .NET 4.5 introduziu uma alteração em como as exceções dentro de um Task
são tratadas. Ou seja, eles são silenciosamente suprimidos.
O raciocínio oficial sobre por que isso foi feito parece ser "queríamos ser mais amigáveis com desenvolvedores inexperientes":
No .NET 4.5, as Tarefas têm muito mais destaque do que no .NET 4, pois são incorporadas às linguagens C # e Visual Basic como parte dos novos recursos assíncronos suportados pelas linguagens. Isso, com efeito, move as Tarefas para fora do domínio de desenvolvedores experientes, para o reino de todos. Como resultado, também leva a um novo conjunto de vantagens e desvantagens sobre o quão rigoroso é o tratamento de exceções.
( fonte )
Aprendi a confiar que muitas das decisões no .NET foram tomadas por pessoas que realmente sabem o que estão fazendo, e geralmente há uma boa razão por trás das coisas que eles decidem. Mas este me escapa.
Se eu estivesse projetando minha própria biblioteca de tarefas assíncronas, qual é a vantagem de engolir exceções que os desenvolvedores do Framework viram que não estou vendo?
Respostas:
Pelo que vale a pena, o documento ao qual você vinculou fornece um exemplo de caso como justificativa:
Não estou convencido disso. Ele remove a possibilidade de um erro inequívoco, mas difícil de rastrear (falha misteriosa do programa que pode ocorrer muito depois do erro real), mas o substitui pela possibilidade de um erro completamente silencioso - que pode se tornar um problema igualmente difícil de rastrear posteriormente no seu programa. Isso parece uma escolha duvidosa para mim.
O comportamento é configurável - mas, é claro, 99% dos desenvolvedores vão apenas usar o comportamento padrão, nunca pensando sobre esse problema. Portanto, o que eles selecionaram como padrão é muito importante.
fonte
op1
, certo? Se aquele não for tratado, o processo será interrompido, certo?op1
a exceção nemop2
a exceção derrubariam o programa. A vantagem é que você tem a oportunidade de observar os dois. Mas se não o fizer, os dois serão engolidos. Eu poderia estar errado, no entanto.TL; DR - Não , você não deve simplesmente ignorar as exceções silenciosamente.
Vamos olhar para as suposições.
MS tem algumas pessoas realmente brilhantes na equipe, sem dúvida. Eles também têm um número de gerentes e executivos ... sem noção, e que sempre tomam más decisões. Por mais que gostássemos de acreditar no conto de fadas do cientista tecnicamente experiente que conduz o desenvolvimento do produto, a realidade é muito mais sombria.
Meu argumento é que, se o seu instinto lhe diz que algo pode estar errado, há uma boa chance (e precedentes anteriores) de estar errado.
Como lidar com exceções nesse caso é uma decisão de fatores humanos, não uma decisão técnica. Vagamente, uma exceção é um erro. A apresentação do erro, mesmo se mal formatada, fornece informações críticas para o usuário final. Ou seja, algo deu errado.
Considere esta conversa hipotética entre o usuário final e um desenvolvedor.
Nosso pobre, felizmente hipotético desenvolvedor, agora precisa descobrir o que deu errado na cadeia de eventos. Onde estava?
Notificação do manipulador de eventos -> Rotina para manipular o evento -> Método acionado pelo manipulador -> início da chamada assíncrona -> as 7 camadas da rede OSI -> transmissão física -> faça backup das 7 camadas da rede OSI -> serviço de recebimento -> método chamado pelo serviço -> ... -> resposta de retorno enviada pelo serviço -> .... -> recebimento assíncrono -> processamento de resposta assíncrona -> ...
E observe que eu encaminhei vários caminhos de erro em potencial lá.
Depois de abordar algumas das suposições subjacentes, acho que fica mais claro por que suprimir discretamente as exceções é uma má idéia. Uma exceção e uma mensagem de erro associada é um indicador importante para os usuários de que algo deu errado. Mesmo que a mensagem não faça sentido para o usuário final, as informações incorporadas podem ser úteis para o desenvolvedor na compreensão do que deu errado. Se tiverem sorte, a mensagem chegará à solução.
Acho que parte do problema aqui é que uma exceção tratada incorretamente irá travar seu aplicativo. Suprimindo as exceções, o aplicativo não falha. Existe alguma validade para isso, já que o objetivo do assíncrono é permitir que o aplicativo continue trabalhando enquanto os dados estão sendo recuperados. Não é uma extensão lógica dizer que, se você continuar operando enquanto aguarda os resultados, uma falha na recuperação também não deve travar o aplicativo - a chamada assíncrona é implicitamente declarada como não sendo importante o suficiente para finalizar o aplicativo.
Portanto, é uma solução, mas está resolvendo o problema errado. Não é preciso muito esforço para fornecer um wrapper para o tratamento de exceções, para que o aplicativo possa permanecer em execução. A exceção é capturada, a mensagem de erro é lançada na tela ou registrada e o aplicativo pode continuar em execução. Suprimir a exceção implica que ignorar erros ficará OK e que seu teste garantirá que as exceções nunca escapem ao campo de qualquer maneira.
Portanto, minha avaliação final é que essa é uma tentativa incompleta de resolver um problema criado ao levar as pessoas a um modelo assíncrono quando não estavam prontas para mudar seu pensamento para essa abordagem.
fonte