.NET Service Windows avec minuterie cesse de répondre
J'ai un service windows écrit en c#. Il dispose d'une minuterie à l'intérieur, qui se déclenche certaines fonctions sur une base régulière. Donc le squelette de mon service:
public partial class ArchiveService : ServiceBase
{
Timer tickTack;
int interval = 10;
...
protected override void OnStart(string[] args)
{
tickTack = new Timer(1000 * interval);
tickTack.Elapsed += new ElapsedEventHandler(tickTack_Elapsed);
tickTack.Start();
}
protected override void OnStop()
{
tickTack.Stop();
}
private void tickTack_Elapsed(object sender, ElapsedEventArgs e)
{
...
}
}
Il travaille depuis un certain temps (comme les 10 à 15 jours), puis il s'arrête. Je veux dire que le service affiche comme la course, mais il ne fait rien. - Je faire de l'abattage et le problème peut être la minuterie, parce que, après l'intervalle, il n'appelle pas la tickTack_Elapsed fonction.
Je pensais à le réécrire sans une minuterie, à l'aide d'une boucle, ce qui arrête le traitement pour la quantité de temps que j'ai mis en place. Ce n'est pas non plus une solution élégante et je pense qu'il peut avoir certains effets secondaires concernant la mémoire.
La Minuterie est utilisée dans le Système.Minuteries d'espace de noms, l'environnement est Windows 2003. J'ai utilisé cette approche dans deux services différents sur des serveurs différents, mais les deux est la production de ce comportement (c'est pourquoi j'ai pensé que c'est en quelque sorte lié à mon code ou le framework lui-même).
N'quelqu'un a connu ce problème? Quel est le problème?
Edit:
J'ai édité les deux services. On a obtenu une belle try-catch partout et de plus en plus de l'exploitation forestière. La deuxième a un timer de loisirs, sur une base régulière. Aucun d'entre eux cessé, depuis, de sorte que si cette situation reste pour une autre semaine, je vais fermer cette question. Je vous remercie pour tout le monde jusqu'à présent.
Edit:
Je ferme cette question, parce que rien ne s'est passé. Je veux dire, j'ai fait quelques changements, mais ces changements ne sont pas vraiment pertinent dans cette affaire et les deux services sont en cours d'exécution sans aucun problème depuis. S'il vous plaît marquer comme "Fermé pour ne pas pertinente".
- Il n'y a rien dans le journal des événements après le minuteur s'arrête en cours d'exécution?
- Rien du tout. Je peux attraper le tickTack_Elapsed fonction, mais il n'est pas appelé plus. Ainsi, le journal indique que le démarrage du service que j'ai obtenu des événements toutes les 10 minutes, mais après un moment il s'arrête sans message d'erreur ou quoi que ce soit d'autre. Puis-je me connecter en quelque sorte plus de détails?
- ne fermez pas la question, parce que d'autres peuvent trouver l'information utile; accepter une réponse à la place
Vous devez vous connecter pour publier un commentaire.
Comme de nombreux répondants ont souligné les exceptions sont avalés par la minuterie. Dans mon windows services-je utiliser le Système.Le filetage.Minuterie. Il a Changer(...) la méthode qui vous permet de démarrer/arrêter la minuterie. Place Possible à l'exception de la réentrée problème - dans le cas où tickTack_Elapsed exécute plus de délai. Habituellement, j'écris de la minuterie de la boucle comme ceci:
Vous pouvez également
lock(...)
votre boucle principale à protéger contre la réentrance.les exceptions non gérées dans les minuteries sont avalés, et ils silencieusement arrêter la minuterie
envelopper le corps de votre minuterie code dans un bloc try-catch
J'ai vu cela à la fois avec minuterie, bouclés et des services. Généralement le cas, c'est qu'une exception est interceptée qui arrête le chronomètre ou une boucle de fil, mais ne redémarre pas dans le cadre de l'exception de récupération.
À vos autres points...
Je ne pense pas qu'il y est quoi que ce soit "élégant" à propos de la minuterie. Pour moi sa plus simple à voir un bouclage de l'opération dans le code de la minuterie méthodes. Mais l'Élégance est subjectif.
Problème de mémoire? Pas si vous l'écrire correctement. Peut-être un processeur fardeau si votre Fil.Sleep() n'est pas situé.
http://support.microsoft.com/kb/842793
C'est un bug connu qui a refait surface dans le Cadre de plus d'une fois.
La meilleure solution connue: ne pas utiliser les minuteries. J'ai rendu ce bug inefficace en faisant un bête "while (true)" en boucle.
Votre kilométrage peut varier, afin de vérifier avec votre combinaison de OS/Cadre bits.
Question intéressante. Si c'est vraiment juste le temps liés (c'est à dire pas une exception), alors je me demande si vous pouvez simplement recycler périodiquement la minuterie - c'est à dire
Vous pourriez probablement fusionner des segments de ce avec la
OnStart
/OnStop
etc afin de réduire la duplication.Avez-vous vérifié les journaux d'erreur? Peut-être que vous manquez de minuteries en quelque sorte. Peut-être que vous pouvez créer un timer lors de l'initialisation de la ArchiveService et passez le Démarrage des trucs.
J'ai fait exactement la même chose que vous dans quelques projets, mais n'ont pas eu le problème.
Avez-vous de code dans le tickTac_Elapsed qui peut en être la cause? Comme une boucle qui n'en finit pas ou une erreur qui arrête le chronomètre, à l'aide de threads et d'attendre la fin de ceux-ci et ainsi de suite?