0

J'ai un programme Windows Mobile qui accède à un périphérique connecté via une DLL tierce. Chaque appel à l'appareil peut prendre une durée inconnue, de sorte que chaque appel inclut une propriété timeout. Si l'appel prend plus de temps que le délai spécifié pour retourner, la DLL déclenche à la place une exception que mon application attrape sans problème.Problème lors de l'utilisation de UnhandledException dans l'application Windows Mobile

Le problème que j'ai est de fermer l'application. Si mon application a appelé la DLL et attend que le délai d'expiration se produise, et que je ferme ensuite l'application avant que le délai ne se produise, mon application se bloque et nécessite le redémarrage du PDA.

Je peux m'assurer que l'application attend le délai avant la fermeture, dans des conditions normales. Cependant, j'essaye d'employer AppDomain.CurrentDomain.UnhandledException pour attraper n'importe quelles exceptions non manipulées dans le programme et utiliser l'événement pour attendre que ce délai en attente se produise ainsi le programme peut être fermé finalement.

Mon problème est que cet événement ne semble pas rester assez longtemps. Si je mets une ligne MessageBox.Show("unhandled exception"); dans l'événement, puis que je lance une nouvelle exception non gérée depuis le formulaire principal de mon application, je vois la boîte de message pendant une fraction de seconde, puis disparaît sans avoir cliqué sur le bouton OK. La documentation que j'ai trouvée sur cet événement suggère qu'au moment où elle est appelée, l'application est entièrement fermée à la fermeture et que la fermeture ne peut pas être arrêtée, mais je ne pensais pas que cela signifiait que la méthode événementielle elle-même ne finis pas. Qu'est-ce qui donne (je suppose que c'est la question)?

Mise à jour: Dans Windows Vista (plein), cela fonctionne comme prévu, mais seulement si j'utilise l'événement Application.ThreadException, qui n'existe pas dans .Net CF 2.0.

+0

Votre appel (?) De longue durée à la DLL n'est-il pas annulable pour la première fois? Juste pour être sûr ... – Marcel

+1

Je pourrais imaginer présenter un contrôle qui nécessite l'interaction de l'utilisateur ne fonctionnerait pas correctement dans ce cas - et si vous écrivez du texte dans un fichier journal à la place? Vous pouvez également essayer de placer un try-catch dans la méthode UnhandledException pour savoir si le MessageBox lui-même lance une ApplicationClosingException (je viens juste de le faire) ou quelque chose comme ça. –

+0

@Marcel: l'appel de longue durée n'est pas annulable de quelque façon que je puisse comprendre, donc pour l'instant je suis coincé en attente de l'achèvement. L'appareil en question est un lecteur de bande magnétique; Pour l'utiliser, vous devez appeler la méthode read sur un thread séparé, puis attendre qu'une carte soit balayée ou que l'exception timeout soit levée. S'il y a une lecture exceptionnelle lorsque je ferme l'application, je dois interroger et attendre que le délai d'attente soit levé avant de permettre la fermeture de l'application. – MusiGenesis

Répondre

3

J'ai également rencontré ce problème. C'est un problème connu dans .NET CF (v2.0), mais je l'ai aussi eu lors de l'utilisation de la v3.5 (bien que les situations dans lesquelles cela se produit soient plus spécifiques). Vous pouvez trouver le (ancien et toujours actif) rapport de bug here.

Appel MessageBox.Show() provoque la fermeture immédiate, mais dans mon cas il y avait deux solutions de contournement: 1) Appelez le MessageBox.Show() une deuxième fois. Il bloque ensuite jusqu'à la fermeture par l'utilisateur. Vous pouvez vérifier le premier MessageBox.Show() fermé prématurément en vérifiant le DialogResult. Je ne me souviens pas quel résultat il est retourné exactement quand il a échoué, je me souviens qu'il donne un résultat non-défaut.

2) Créez un Formulaire personnalisé et appelez ShowDialog() pour cela. Cela a fonctionné pour moi, mais d'autres ont signalé que cela ne fonctionnait pas. Vous pouvez également appeler Show() et le bloquer vous-même (n'oubliez pas d'appeler Application.DoEvents() pour continuer à traiter les événements).

Questions connexes