11
votes

Pourquoi n'est-il pas possible d'attraper la méthodexception manquante?

J'ai une dépendance sur .NET 2.0 SP2 dans mon application déployée ClickOnce (Le ApplicationDeployment.CurrentDeployment.CurceckfordetaileDUpdate (FALSE) La méthode est SP2 uniquement).

Je voudrais vérifier si SP2 est présent lors du démarrage de l'application. J'ai essayé de détecter cela en attrapant la méthodexception manquante après avoir appelé une méthode SP2 uniquement. xxx

Le code dans la capture ne s'exécute jamais lorsque cela s'exécute sur .NET 2.0 sans SP2. L'exception n'est capturée que par le appdomain.CurrentDomaine.unhandleXception gestionnaire d'événements.

Comment est-il possible que la méthodexception manquante ne soit pas attrapée? Je peux imaginer que c'est un cas particulier - le CLR frappe une méthode qui n'existe pas et qu'il n'est pas possible de transmettre ceci au bloc de capture. Je voudrais comprendre le principe derrière cela.

Quelqu'un a des ressources sur ce problème? Y a-t-il d'autres exceptions qui ne peuvent pas être capturées dans un bloc de capture?


0 commentaires

4 Réponses :


15
votes

Je soupçonne que cela se passe à JIT Time, avant que la méthode soit même correctement entrée - c'est-à-dire avant que votre bloc de prise ne soit frappé. C'est possible que si vous attrapez manquezMethodException dans la méthode appeler , qui triera la sortie ... en particulier si vous décorez checkdotnet2sp < / code> avec méthodimpl [méthodimploption.noinlining] . On sonne toujours comme ça serait assez désagréable.

Vous pouvez toujours vérifier la présence de la méthode avec une réflexion plutôt que d'essayer de l'appeler.


0 commentaires

12
votes

Il y a quelques exceptions à exception définies comme "non recouvertes". L'un d'entre eux est manquant, méthodexception , car si une méthode est manquante dans une classe, il s'agit d'une erreur sévère et nécessite de décharger la classe et de recharger une nouvelle classe à récupérer, ce qui ne peut pas être fait de manière tritiquement (si tous).

Pour récupérer, vous devez réinstaller, vérifier les versions des assemblys, vérifier si les images PE sont valides, etc.

Si tout ce que vous voulez savoir, si SP2 est installé, la méthode par défaut utilise une application bootstrap qui vérifie simplement la version installée. Si tout va bien, il exécute l'application, sinon cela montre un bon message.


mise à jour demandée par OP:

D'autres exceptions qui sont difficiles à attraper ou non (peut dépendre de votre version de .NET, c'est-à-dire .NET 4.0 Ajout plus de non-incesses): OutofMemoryException (peut être pris quand il est synchrone), StackoverFlowException (ne peut jamais être attrapé), threadabortexception (peut être attrapé, mais est spécial car il sera automatiquement en perfectionner à la fin du bloc de capture), badimageformatException < / code> et manquantManifestreSourceException Si vous essayiez de l'attraper dans l'assemblage, lancez l'exception (si vous le chargez de manière dynamique, comme avec manquanteMethodexception , vous êtes capable d'attraper ce). Et en général, toute exception qui n'hérite pas de exception est difficile à capter (mais vous pouvez les attraper avec un bloc d'essai générique / track).

Il y en a d'autres, mais les trois premiers ci-dessus sont ceux que vous rencontrerez le plus souvent dans la pratique.


2 commentaires

Pourriez-vous s'il vous plaît répertorier d'autres types d'exception «irrécupérables»?


Avez-vous une référence pour ces exceptions «non recouvertes»? Je vois qu'il est appelé dans Application.DispatcherunhandleXception , mais je ne trouve pas d'informations définitives.



4
votes

Une exception est levée sur une étape de compilation JIT, de sorte que vous ne comprenez pas la méthode. Essayez cette version: xxx


2 commentaires

Afaict, cette méthode déchargera toujours l'application lors de l'erreur car elle est considérée comme irrécupérable.


J'ai testé et vérifié que cette réponse fonctionne correctement dans .NET CORE 3.1



3
votes

Vous pouvez utiliser la réflexion pour voir si la méthode existe. xxx


1 commentaires

Notez que cela ne fonctionnera pas si l'exception est réellement lancée par le compilateur JIT. Cela ne fonctionnera que lorsque l'appel à la méthode est lui-même fait par réflexion.