Je parcourais la source de référence .NET et trouvé ce gemme dans buttonbase.cs à la ligne 408: Question étant, que motiverait quelqu'un à utiliser le ExceptionThrowr code> Drapeau sur simplement l'écrivant comme P> try
{
OnClick();
}
catch
{
SetIsPressed(false);
ReleaseMouseCapture();
throw;
}
5 Réponses :
Si vous utilisez Essayez, attrapez une exception doit être lancée deux fois. Avec essayer, finalement une seule exception est lancée, il est donc , en particulier grève> si ce code est appelé souvent. P>
Si le code exceptionnel b> est appelé souvent b>, il n'est plus exceptionnel. Performance Optimisation du chemin du code d'erreur est généralement un retour sur investissement médiocre.
+1 belle réponse, était l'un des premiers à uppote ... mais j'ai vu mes actions d'optimisations et je dois vous dire que, ce n'est pas vrai - le code n'est pas "beaucoup plus efficace" en fait, il est en fait Seulement 10-15% plus efficaces, ce qui signifie qu'il y a une optiomaztion en place et il n'y a pas de 2 promenades de pile qui se produisait comme on pourrait penser à jeter l'exception à nouveau dans le premier exemple. Voici une application de test semble être un minuscule peu plus rapide d'utiliser enfin le tour, si minuscule en fait que Cela ne vaut pas la peine d'écrire le code obscurci avec enfin clause.
Donc, de quoi nous parlons est probablement 2 à 3 instructions supplémentaires étant exécutées sur le TRY / CATTER CODE> Exemple qui envisagent qu'il existe un appel de méthode réel à l'intérieur de l'exemple réel, il s'agirait d'une optimisation oscillable et peut être ignorée En tant qu'amélioration de la perforation ... plus ou moins mais toujours +1 pour le Nice Catch B>
Ce n'est pas seulement sur la performance. En prétendant gérer des exceptions, mais ne les manipule pas réellement, complique également le débogage car le débogueur ne peut pas savoir à l'avance, lorsque l'exception est lancée, que ce soit manipulé. Si votre personnalisé Cliquez sur CODE> Hangler jette une exception que vous ne connaissez pas et que vous avez débogué votre programme, vous voulez généralement savoir exactement i> ce qui se passe. Éviter le double lancer code> aide ici.
J'ai presque toujours mon debugger mis en place pour arrêter sur des exceptions levées. De cette façon, s'il y a une exception qui est jetée sur presque toutes les couronnes, j'essaie de le prendre en charge en utilisant une alternative non lancée. Le cadre utilisé pour avoir de nombreuses API où vous ne pouviez pas tester une exception non exceptionnelle sans envelopper un Essayez ... Catch code> Block autour de celui-ci (par exemple, le Analysse () < / Code> Famille de méthodes), mais la situation s'est considérablement améliorée au fil des ans (par exemple, tryparse () code>).
La raison de ce code est deux fois. Oui, un Greg mentionne, il ne nécessite pas de repousser l'exception .. mais ce n'est pas vraiment la raison.
La vraie raison est une des sémantiques. Des exceptions ne doivent pas être utilisées pour gérer le flux de contrôle. Ce que cela fait est de faire face au fait que si une exception est lancée dans un bouton, elle peut laisser l'état visuel des boutons comme "pressé". Ce n'est vraiment pas "manipuler" l'exception. Ceci est simplement corrigé un problème visuel dans le cas où une exception est lancée. P>
Ce code ne se soucie pas de l'exception, et cela ne veut pas attraper toutes les exceptions car c'est une mauvaise pratique. En outre, le code ne fait rien avec l'exception .. C'est juste dire «Hé, si nous arrivons à la fin de la fonction, nous sommes tous bien. Si nous ne le faisions pas, alors permet de réinitialiser l'état du bouton juste pour Assurez-vous ". P>
Donc, ce n'est pas une réelle gestion des exceptions, en tant que tel, il n'atteint pas une exception. Il remarque que une exception a été lancée et fait un certain nettoyage. P>
EDIT: P>
Cette méthode pourrait être moins controversée et gagner beaucoup plus de sens si c'était simplement renommé comme ça, Supprimer toute référence aux exceptions: P>
00:00:00.0000137 00:00:00.0000248 00:00:00.0000251
De toute façon, c'est un code de code agréable et intelligent qui évite le coût de la collerie d'une clause de capture. Mais je suis un peu iffy sur la renommée du bool code> à CleanUPequired code>, car il se cache exactement par quel mécanisme nous sommes venus le savoir. À un moment donné, vous pouvez obtenir un peu aussi i> intelligent, et la prochaine chose que vous savez, quelqu'un est sur Stackoverflow demandant à tout le monde, "WTF pensaient-ils quand ils faisaient cette i>?" ;-)
Cela semble plus d'une distinction stylistique que fonctionnelle. En fait, il semble que vous réémayez la sémantique d'une capture juste à cause du nom. L'autre code posé par intérim ou exception n'utilise certainement pas d'indicateurs pour implémenter le nettoyage.
@Mitch - Je ne pense pas que ce soit stylistique du tout. OnClick () exécute probablement le code écrit par l'utilisateur, de sorte que cela puisse faire à peu près n'importe quoi. Bien qu'une prise fonctionnait tout aurait fonctionné, c'est des frais généraux supplémentaires sans raison valable. Ce code remarque simplement que l'appel ONCLICK n'a pas revenu normalement et fait un certain nettoyage. Cela ne se soucie pas de quoi ou comment, alors pourquoi attraper quelque chose que vous ne vous souciez pas réellement?
@MYSTERMANIMEME, vous semblez suggérer qu'il existe une certaine exigence qui exige que les déclarations code> code> traitent une exception, lorsque la capacité de réthorez-les leur permet d'être utilisées dans la juste cette situation. En outre, la question est de savoir s'il existe une différence fonctionnelle i>, pas un style ou une différence sémantique.
En outre, qu'est-ce que ce "surcharge" imposé par une prise? Est-ce plus sur le dessus que les bugs possibles introduits par 3 locum supplémentaires et un drapeau déroutant? Au-delà de cela, je
@Mitch - C'est des frais généraux supplémentaires parce que vous devez repousser l'exception, ce qui provoque une deuxième pile déroulant. Et oui, ça fait. Je l'ai testé. Retirout l'exception double la quantité de temps nécessaire pour gérer l'exception.
@Mystereman, je pense que vos tests de performance testent VS, pas C # - Si j'exécute vos tests sans débogger joint, l'augmentation du temps est inférieure à 20 microsecondes. Voir ideone.com/4e6bna pour ce que je considérerais comme une comparaison plus appropriée (<1% de changement mesuré) . Mais tous les tests PERF ne sont vraiment pas le point lorsque le code est plus difficile à lire et à être performant avec essayer / attraper. "Les programmes doivent être écrits pour que les personnes à lire, et que des machines ne soient incidemment à exécuter."
@Mitch - Je ne suis pas sûr de ce que vous pensez que votre code est testé, mais ce n'est pas correct. Votre Docleanup hébergente l'exception et ne le reproduit pas. En fait, vous n'avez pas de reproduction d'une exception là-bas. Oui, courir dans un débogueur est plus lent, mais il s'agit simplement d'illustrer l'exemple. Quand j'exécute mon code sans débogueur, c'est beaucoup plus rapide, mais toujours le Rethow est deux fois plus lent. Vous pouvez certainement affirmer que le code lisible est important, mais vous plaidiez qu'il n'y avait pas de surcharge de performance. C'est tout simplement faux, c'est deux fois plus cher à Retirhow.
@Mystereman, belle prise sur l'erreur de capture. Voir IDEONE.COM/7ICEAF pour le test mis à jour. Je ne dis pas qu'il n'y a pas d'impact sur la performance, mais qu'une micro-optimisation des performances n'est pas pertinente dans un gestionnaire de bouton pour un cas exceptionnel compte tenu de la diminution de la lisibilité.
Eh bien, une raison pour laquelle je peux penser est (à l'avenir) en ajoutant la nécessité d'attraper une exception spécifique, tout en maintenant le même comportement de nettoyage. Examinez les exemples suivants: vs. P>
une petite note: onclick code> est une méthode virtuelle. Il devrait être remplacé par le code écrit par l'utilisateur, qui peut lancer des exceptions arbitraires. Le code telle que écrit exprime la sémantique du "nettoyage du désordre fait par ceux qui envahissent cette méthode". P>
Apparemment, il y a des effets secondaires au lancer Cet article de blog donne deux exemples de la façon dont La question Affichage de la trace de la pile d'exception ré-lancée, plutôt que de la trace de pile à partir de point de lancer donne un scénario permettant de reproduire l'exception provoque une opération différente dans Visual Studio. P> ; code> qui supprimera toujours les informations de trace de pile jusqu'à au moins .net 2. J'imagine que cette syntaxe a été utilisée pour contourner la mise en œuvre de lancer; code> sur les premières versions du cadre. P>
à lancer; code> n'est pas équivalent à ne jamais attraper une exception du tout. p>
Je devrais penser que c'est la vraie réponse. Évitez de rejeter et avez donc une trace précise de la pile.
On dirait qu'il serait correct de vérifier certaines exceptions sur les affaires personnalisées lors des prises afin que vous puissiez faire autre chose. Cela a l'air à peu près à casser la pile pour rien. Un essai vide {} Catch {} est pire qu'un lancer pour des raisons de signification et que vous écrasez simplement la pile au-delà de cela.
Je pense qu'il n'y a pas de différence entre les deux. Cependant, si vous écrivez quelque chose comme ça, comme le code changera des heures supplémentaires, il y aura un jour que vous avez besoin d'informations à partir de l'exception et vous finirez par utiliser Catch. Petits changements, cependant.