Nous exécutons une application C # Console qui commence plusieurs threads pour faire du travail. La fonction principale ressemble à ceci comme suit:
new Thread(SomeObj.StartFunc).Start();
8 Réponses :
Vous devez avoir un bloc de capture similaire au niveau supérieur de la fonction que chaque thread fonctionne. S'il y a une exception non capturée sur un thread, elle tuera l'application et le bloc de capture sur le fil principal ne va pas aider. P>
Le fil a un bloc d'essai / attraper dans sa fonction de niveau supérieur.
Que voulez-vous dire par "... chaque fil fonctionne" i>? Voulez-vous dire "... chaque fil fonctionne sur" i>? Ou autre chose?
Cela pourrait peut-être être la fonction Logging.Log qui jette votre exception. P>
La fonction de journalisation est simple et il y a beaucoup d'espace disque disponible. Le programme conserve un seul streamwriter ouvert lorsqu'il est exécuté et protège l'accès à une section de verrouillage {}.
Un programme de console quitte la limite lorsque la fonction principale se ferme. Étant donné que Dowork ne ressentait que quelques threads, il renvoie le contrôle au principal tout de suite, et puisque le principal n'a rien d'autre pour le faire et le programme se termine. A cette époque, les fils engendrés par Dowork sont également tués. p>
que cela a fonctionné avant, soit il y avait quelque chose dans Dowork () à attendre sur ces threads qui revient maintenant tout de suite (sont cassés) ou que la partie fonctionne toujours mais un fil qui prenait longtemps pour retourner maintenant retourne tout de suite. P>
La fonction Dowork () ne renvoie pas avant que tout le travail ne soit effectué et que tous les threads ont été fermés. Le programme a bien fonctionné pendant des années et a traité plus d'un million d'articles de travail.
Attendez ... Je pensais que seuls les threads de fond sont tués lorsque l'application qui les engendrera?
@Will: Je pense que c'est le comportement d'un service Windows. D'autres applications Windows fonctionnent comme Joel décrit
Cela n'explique pas pourquoi logging.log ("fini"); n'est pas appelé.
J'ai réussi à faire disparaître des programmes sans une trace de la même manière à vous (pas de traces d'exception ni de messages de connexion de terminaison) dans le passé. Presque tout le temps, il était lié à tuer la pile (le nom de ce site me rappelle toujours). P>
Il est possible que vous essayiez soudainement de traiter beaucoup plus de données que d'habitude ou d'utiliser des routines de re-entrant ou d'être «intelligent» avec des pointeurs. P>
Disclaimer: Mon expérience était avec une application Win32 C ++, pas C #. P>
Cela pourrait être une fuite de mémoire. Si votre application prend trop de mémoire, Windows le tuera. Vous pouvez vérifier la quantité de mémoire que vous utilisez: si elle pousse au fil du temps, vous pouvez avoir une fuite de mémoire. P>
Une autre possibilité est que quelque part, vous avez un environnement appelant environnement.exit (). Essayez une recherche de texte complète via votre code pour vérifier. Vous ne savez jamais! P>
Merci pour les conseils. L'utilisation de la mémoire ne semble pas grandir et la fonction de sortie () était l'une des premières choses que nous avons vérifiées :)
Il est possible que l'un des threads que la méthode de la dowork se reproduit est de lancer une exception. Le comportement par défaut dans ce cas est que le processus se termine. Vous pouvez arrêter cela de se produire en utilisant le appdomain.unhandleXception a > événement pour remplacer le comportement par défaut. P>
Quelle est l'identité que vous utilisez pour exécuter l'application de la console?
En outre, vous pouvez utiliser SetConsolectrlHandler pour capturer les événements de la console. Regardez Ce blog post pour plus de détails. Nous avons eu un problème similaire lorsque la demande de console était exécutée sous un compte de service et que cela se terminerait occasionnellement. Je ne sais pas si c'est ce que vous rencontrez. Faites-moi savoir que je peux poster du code. P>
Mise à jour: On dirait que votre scénario ressemble à ce que nous avions expérimenté. Dans votre gestionnaire d'événements de console, vous devez vérifier l'événement logoff em> et retourner vrai. Regardez Cet article de KB . P> public static void inputHandler(ConsoleCtrl.ConsoleEvent consoleEvent)
{
if (ConsoleEvent == ConsoleCtrl.ConsoleEvent.CtrlLogOff)
return true;
return false;
}
Il est exécuté comme une tâche planifiée d'un compte avec des privilèges administratifs. J'ai ajouté le gestionnaire et l'a modifié pour enregistrer des événements, le laisser courir pendant un moment de voir s'il frappe!
J'ai ajouté la journalisation et l'événement Ctrllogoff est en effet ce qui provoque la sortie de la tâche planifiée. Problème résolu, même si nous aimerions toujours savoir où vient l'événement Ctrllogoff!
Comment vous pouvez-vous retourner un booléen d'une fonction vide?
Soyez prudent; Il y a quelques exceptions à exception qui ne peuvent pas être attrapées: OutofMemoryException et StackoverFlowException. P>
Par conséquent, votre programme mourra terriblement, mais silencieusement. P>
Ouais, mais je m'attendrais à ce que cela déclenche debugdiag et de loger une décharge de crash.
Afaik OutofMemoryException code> peut être attrapé.
Est-ce qu'il fait toujours tomber / arrêter au même point? Où est-ce fonctionnant? Est-ce que quelqu'un / quelque chose pourrait tuer le processus?
Nous pourrions vraiment faire avec plus de détails sur ce qui se trouve dans la méthode de la Dowork ...
Les arrêts se produisent à des moments aléatoires, cette semaine 5 fois au total. En théorie, je suppose que quelqu'un pouvait se connecter et tuer le processus, mais cela sonne un peu paranoïaque.
Que fait Dowork après avoir créé et commencer les threads? Est-ce que ça va dans une boucle infinie, sortie tout de suite, tente de rejoindre les threads de fond, ou quoi?
Il va dans une boucle infinie. Les threads de fond mettent à jour leur statut dans un tableau protégé par Lock {}. Lorsqu'un thread est terminé, il supprime sa propre entrée de la matrice.
Cette application est-elle conçue pour (a) faire beaucoup de travail qui prend une quantité de temps finie puis de la sortie ou (b) fonctionne pour toujours jusqu'à la fin manuellement?
Ajoutez plus de journalisation cohérente de sorte que vous ajoutez des lignes de journalisation à des points de contrôle réguliers et à des fonctions constamment réveillantes. De cette façon, vous devriez être capable de déterminer le dernier point «toujours de travail» connu.
Accepté Re: le paranoïaque mais j'ai eu quelqu'un qui a fait cela dans le passé. Ils ne savaient pas ce que c'était alors ils l'ont tué quand ils l'ont vu et ne savaient pas à demander.