Je viens d'apprendre que .NET 4.5 a introduit un changement dans la gestion des exceptions à l'intérieur d'un Task
. À savoir, ils sont discrètement supprimés.
Le raisonnement officiel pour expliquer pourquoi cela a été fait semble être "nous voulions être plus amicaux avec les développeurs inexpérimentés":
Dans .NET 4.5, les tâches ont beaucoup plus d'importance que dans .NET 4, car elles sont intégrées aux langages C # et Visual Basic dans le cadre des nouvelles fonctionnalités asynchrones prises en charge par les langages. En effet, cela déplace les tâches hors du domaine des développeurs expérimentés dans le domaine de tout le monde. En conséquence, cela conduit également à un nouvel ensemble de compromis sur la sévérité de la gestion des exceptions.
( source )
J'ai appris à croire que de nombreuses décisions dans .NET ont été prises par des gens qui savent vraiment ce qu'ils font, et il y a généralement une très bonne raison derrière les décisions qu'ils prennent. Mais celui-ci m'échappe.
Si je concevais ma propre bibliothèque de tâches asynchrones, quel est l'avantage d'avaler des exceptions que les développeurs du Framework n'ont pas vues?
Réponses:
Pour ce que ça vaut, le document auquel vous avez lié donne un exemple de cas comme justification:
Je n'en suis pas convaincu. Il supprime la possibilité d'une erreur non ambiguë, mais difficile à tracer (mystérieux plantage du programme qui peut se produire longtemps après l'erreur réelle), mais la remplace par la possibilité d'une erreur complètement silencieuse - qui pourrait devenir un problème tout aussi difficile à tracer plus tard. dans votre programme. Cela me semble un choix douteux.
Le comportement est configurable - mais bien sûr, 99% des développeurs vont simplement utiliser le comportement par défaut, sans jamais penser à ce problème. Donc, ce qu'ils ont sélectionné par défaut est un gros problème.
la source
op1
, non? Si celui-ci reste non géré, il fera baisser le processus, non?op1
l'exception niop2
l'exception ne feraient tomber le programme. L'avantage est que vous avez la possibilité d'observer les deux. Mais si vous ne le faites pas, ils seront tous les deux avalés. Je pourrais toutefois avoir tord.TL; DR - Non , vous ne devez pas simplement ignorer les exceptions tranquillement.
Regardons les hypothèses.
MS a sans aucun doute des gens vraiment brillants. Ils ont également un certain nombre de gestionnaires et de cadres qui sont ... sans aucune idée, et qui prennent constamment de mauvaises décisions. Autant que nous aimerions croire le conte de fées du scientifique techniquement avisé qui dirige le développement du produit, la réalité est bien plus sombre.
Je veux dire que si votre instinct vous dit que quelque chose ne va pas, il y a de fortes chances (et un précédent passé) que ce soit faux.
La façon de gérer les exceptions dans ce cas est une décision de facteurs humains, pas une décision technique. En gros, une exception est une erreur. La présentation de l'erreur, même si elle est mal formatée, fournit des informations critiques à l'utilisateur final. À savoir, quelque chose s'est mal passé.
Considérez cette conversation hypothétique entre un utilisateur final et un développeur.
Notre pauvre développeur, heureusement hypothétique, doit maintenant comprendre ce qui s'est mal passé dans la chaîne des événements. Où était-il?
Notification du gestionnaire d'événements -> Routine pour gérer l'événement -> Méthode déclenchée par le gestionnaire -> début de l'appel asynchrone -> les 7 couches du réseau OSI -> transmission physique -> sauvegarder les 7 couches du réseau OSI -> service de réception -> méthode appelée par service -> ... -> retour de réponse envoyé par service -> .... -> réception asynchrone -> traitement de la réponse asynchrone -> ...
Et veuillez noter que j'ai glissé plusieurs chemins d'erreur potentiels là-bas.
Après avoir abordé certaines des hypothèses sous-jacentes, je pense qu'il devient plus clair pourquoi la suppression silencieuse des exceptions est une mauvaise idée. Une exception et un message d'erreur associé est un indicateur clé pour les utilisateurs que quelque chose s'est mal passé. Même si le message n'a pas de sens pour l'utilisateur final, les informations intégrées peuvent être utiles au développeur pour comprendre ce qui n'a pas fonctionné. S'ils sont chanceux, le message mènera même vers la solution.
Je pense qu'une partie du problème ici est qu'une exception mal gérée plantera votre application. En supprimant les exceptions, l'application ne se bloquera pas. Il y a cependant une certaine validité dans ce sens, car le but de l'async est de permettre à l'application de continuer à fonctionner pendant la récupération des données. Ce n'est pas vraiment une extension logique de dire que si vous pouviez continuer à fonctionner en attendant les résultats, un échec de récupération ne devrait pas non plus bloquer l'application - l'appel asynchrone est implicitement déclaré comme n'étant pas suffisamment important pour mettre fin à l'application.
C'est donc une solution, mais elle résout le mauvais problème. Il ne faut pas autant d'efforts pour fournir un wrapper à la gestion des exceptions afin que l'application puisse continuer à fonctionner. L'exception est interceptée, un message d'erreur est affiché à l'écran ou enregistré et l'application est autorisée à continuer de fonctionner. La suppression de l'exception implique que l'ignorance des erreurs sera A-OK et que vos tests garantiront que les exceptions n'échapperont jamais au champ de toute façon.
Donc, mon évaluation finale est qu'il s'agit d'une tentative à moitié cuite de résoudre un problème créé en poussant les gens dans un modèle asynchrone lorsqu'ils n'étaient pas prêts à changer leur façon de penser à cette approche.
la source