2010-04-23 5 views
2

Nous avons une application de bureau WinForms, qui est fortement multithread. 3 threads s'exécutent avec Application.Run et un tas d'autres threads de travail d'arrière-plan. Obtenir tous les threads à fermer correctement était un peu délicat, mais je pensais que je l'ai finalement eu raison. Mais lorsque nous avons réellement déployé l'application, les utilisateurs ont commencé à rencontrer l'application qui ne se terminait pas. Il y a un System.Threading.Mutex pour les empêcher d'exécuter l'application plusieurs fois, ils doivent donc aller dans le gestionnaire de tâches et tuer l'ancien avant de pouvoir l'exécuter à nouveau.L'application ne sort pas avec 0 thread

Chaque thread obtient un Thread.Join avant que le thread principal ne se termine, et j'ai ajouté la journalisation à chaque thread que je génère. Selon le journal, chaque thread qui démarre se termine également et le thread principal se ferme également. Encore plus étrange, l'exécution de SysInternals ProcessExplorer montre que tous les threads disparaissent à la fermeture de l'application. Comme dans, il y a 0 threads (gérés ou non gérés), mais le processus est toujours en cours d'exécution.

Je ne peux pas reproduire cela sur les ordinateurs des développeurs ou dans notre environnement de test, et jusqu'ici je n'ai vu cela que sur Windows XP (pas Vista ou Windows 7 ou Windows Server). Comment un processus peut-il continuer à fonctionner avec 0 threads?

Éditer:

Voici un peu plus de détails. L'une des boucles d'événements héberge une DLL d'interopérabilité Win32 qui utilise un objet COM pour communiquer avec un pilote de périphérique. Je l'ai mis dans son propre thread parce que le pilote de périphérique est sensible au temps, et chaque fois que le thread UI bloque pendant une période de temps significative (comme attendre un appel de base de données), il interfère avec le pilote de périphérique.

J'ai donc modifié le code pour que le thread principal fasse un Thread.Join avec le thread du pilote de périphérique. Cela a en fait causé le blocage de l'application ... il enregistre quelques autres appels sur le thread de l'interface utilisateur après la fin de la jointure, puis tout s'arrête. Si le périphérique est hors tension, le pilote ne démarre jamais et le problème disparaît. Il semble donc que le pilote doit être responsable du maintien de l'application, même après avoir été censé être fermé.

+0

Vérifiez ceci: http: //blogs.msdn.com/oldnewthing/archive/2004/07/23/192531.aspx –

+0

C'est un scénario intéressant, mais ne correspond pas à ce qui se passe. Le processus est complètement éliminable par l'utilisateur via le gestionnaire de tâches, il ne se termine jamais seul. Nous l'avons laissé courir pour 1/2 heure. –

+0

Pourquoi êtes-vous sûr qu'il y a exactement 0 threads? Avez-vous testé cela avec le débogueur? Même le gestionnaire de tâches de Windows XP peut vous montrer le nombre de threads (cependant, vous devez ajouter explicitement cette colonne à l'onglet Processus via Menu> Affichage> Sélectionner les colonnes ...). Je doute qu'il n'y ait réellement aucun fil. Ma première idée serait une impasse dans votre processus de sortie/nettoyage. – SergGr

Répondre

0

Nous n'avons jamais comprendre la racine de la cause programmatique, mais il était une version pilote spécifique qui a causé le problème, et la mise à niveau à un nouveau pilote résolu le problème.

Malheureusement, tout cela est la réponse que je peux donner, si quelqu'un d'autre va un jour un problème similaire ...

0

Est-il possible que les enfants de vos appels Application.Run ne se terminent pas? En outre, qu'est-ce qui cause la fermeture de l'application? Est-ce qu'il se ferme automatiquement lorsque tous les threads sont terminés (ce qui signifie automatiquement que vous avez écrit du code pour cela) ou est-il imité par l'utilisateur?

J'ai eu un problème une fois où il y avait une condition de concurrence dans mon code d'événement "thread complete" qui aboutissait parfois à ce que vous voyez. Les deux derniers threads se termineraient en même temps, déclencheraient l'événement simultanément, et chaque événement déciderait que ce n'était pas le dernier thread, donc l'application continuerait à fonctionner, même si le nombre de threads était nul. Pour résoudre ce problème, j'ai pu trouver et éliminer la condition de concurrence, mais vous pouvez également utiliser une minuterie qui vérifie toutes les secondes ou deux, obtient le nombre de threads, et si aucun n'est encore ouvert, il tue l'application.

+0

Les appels Application.Run se terminent par Application.Exit() sur le thread principal. Je vais essayer d'arrêter les autres appels Application.Run() avant de laisser le thread principal quitter. –

Questions connexes