quelle est la durée maximale d’attente du service Windows pour traiter la demande d’arrêt et comment demander un délai supplémentaire

J’ai écrit un service Windows en C # qui traite beaucoup de données. lorsque nous l’arrêtons, essayez pendant 20/30 secondes, puis lance une exception.

Je souhaite implémenter ServiceBase.RequestAdditionalTime () dans l’événement OnStop.

Je souhaite connaître le délai d’expiration après lequel le service Windows lève l’exception, afin de pouvoir demander un délai supplémentaire juste avant celle-ci.

J’ai cherché mais n’ai pas trouvé cette valeur de délai d’attente d’arrêt par défaut.

J’ai écrit le code suivant pour y parvenir.

protected override void OnStop() { int timeout = 10000; var task = Task.Factory.StartNew(() => MyTask()); while (!task.Wait(timeout)) { RequestAdditionalTime(timeout); } } 

Le code ci-dessus lance une tâche en parallèle au thread principal (la tâche commence à s’exécuter immédiatement), la ligne suivante vérifie si la tâche est terminée ou non toutes les 10 secondes. Si elle n’est pas terminée, elle demande 10 secondes supplémentaires et continue de vérifier jusqu’à ce que la tâche soit terminé.

Bien que plusieurs personnes aient mentionné la HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout registre HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout , selon cet article “Service Control Handler” de Microsoft, cette entrée de registre ne contrôle que le temps maximal qu’un service peut prendre pour se fermer lorsque Windows lui-même est en train d’être arrêté ou redémarré :

<...> pour empêcher un service d’arrêter un arrêt, il existe une limite à la durée pendant laquelle le contrôleur de service attend. Si le service est en cours d’arrêt via le composant logiciel enfichable Services, la limite est de 125 secondes. Si le système d’exploitation redémarre, la limite de temps est spécifiée dans la valeur WaitToKillServiceTimeout <...>

Si Windows ne redémarre pas ou n’est pas en train de s’arrêter , le délai par défaut pendant lequel Windows attendra qu’un service soit arrêté est de 30 secondes. Toutefois, les applications peuvent faire des demandes de temps supplémentaire, qui sera honoré jusqu’à 125 secondes au total (additionné pour toutes les demandes).

Sous Windows Server 2003 et versions ultérieures, ce délai par défaut peut être modifié via la HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServicesPipeTimeout , comme décrit dans cet article du support technique Microsoft (et cette question ServerFault ). Il n’est pas clair si cela s’applique à Windows 7/8/10, car l’article ne mentionne que les versions de serveur.

Si un redémarrage / arrêt a été lancé sur la machine, la valeur de la clé de registre WaitToKillServiceTimeout (si présente) spécifie la durée maximale pendant laquelle Windows autorisera l’application, en remplaçant la valeur par défaut du système d’exploitation.

Cela signifie probablement que les applications ne peuvent pas retarder arbitrairement l’arrêt au-delà de la valeur par défaut (ou de ce que l’administrateur a spécifié via l’entrée de registre WaitToKillServiceTimeout).

Il est défini dans le registre sur la sous-clé:

  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control 

avec la valeur de chaîne WaitToKillServiceTimeout . S’il n’est pas défini, la valeur par défaut est 20000 (ms). Sur ma machine, il semble être réglé sur 12000 (12s). Je ne l’ai jamais touché.

Par défaut, je pense qu’il faut 12 000 millisecondes. Pour le changer, vous devez accéder au registre HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ WaitToKillServiceTimeout et modifier la valeur.

mais vous pouvez définir votre propre temps mort si vous voulez le démarrer ou arrêter la programmation ici, vous définissez votre propre temps mort pour commencer

 TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); service.Start(); service.WaitForStatus(ServiceControllerStatus.Running, timeout); 

et vous définissez ici votre temps libre pour vous arrêter

  TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 

Il suffit simplement de toujours exécuter RequestAdditionalTime , avec le temps maximal que vous attendez de votre service pour son arrêt. Ce n’est pas une erreur que de finir plus tôt que prévu.