Comment arrêter en toute sécurité un thread C # .NET s'exécutant dans un service Windows?
Je suis le maintien d'un bout de code qui ressemble à quelque chose comme ça. C'est un service Windows qui effectue des travaux, toutes les 30 minutes. Le ActualWorkDoneHere méthode prend environ 30 secondes à s'exécuter, mais si elle est arrêtée lors de l'exécution, il peut laisser les choses dans un mauvais état. Quelle est la meilleure façon d'empêcher que cela se produise? Devrais-je remplacer le While(true) avec une valeur de type boolean qui est à false dans la méthode onstop (suppression de l'Abandon de thread d'appel)? Est-il un moyen de savoir si un thread est de dormir?
namespace WorkService
{
public partial class WorkService : ServiceBase
{
private Thread _workerThread = null;
public WorkService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_workerThread = new Thread(new ThreadStart(DoWork));
_workerThread.Start();
}
protected override void OnStop()
{
_workerThread.Abort();
}
static void DoWork()
{
int sleepMinutes = 30;
while (true)
{
ActualWorkDoneHere();
System.Threading.Thread.Sleep(new TimeSpan(0, sleepMinutes, 0));
}
}
}
}
source d'informationauteur Stimy | 2009-11-19
Vous devez vous connecter pour publier un commentaire.
Quand j'ai quelque chose comme ça, j'ai l'habitude d'utiliser un
ManualResetEvent
. Cette fonction est définie dans leStop()
appel. Puis-je attendre avec un délai d'attente:La mise en œuvre de soi-même est la seule option sûre. Même si vous trouvez un moyen de savoir si un thread est en veille, vous aurez toujours une condition de course si vous essayez de le tuer (parce qu'elle est susceptible de commencer à traiter une fois que vous vérifiez et avant de le tuer).
Au lieu de Fil.Le sommeil vous pourriez par exemple le sommeil 500ms et de vérifier si l'abandon du drapeau est toujours faux, le sommeil un autre 500ms etc. avant de 30mins passe, puis faire le travail, etc. (ce serait une approche pragmatique). Si vous voulez quelque chose de plus élégant, vous pouvez utiliser un ManualResetEvent avec un délai d'attente à attendre que le thread principal de signalisation que son temps pour abandonner.
Wow tout le monde fait ce si compliqué. Utilisez une Minuterie:
Sur les courses:
Le post original avait une course en OnStop qui a été résolu. Pour autant que je sais mettre le service à l'état d'arrêt ne sera pas abandonner pool de threads les threads qui sont utilisés pour le service de la minuterie. La condition de la minuterie de cuisson et le service est arrêté en même temps n'est pas pertinent. ActualWorkDoneHere() va exécuter, ou n'exécute pas. Les deux sont des conditions acceptables.
Voici une façon de le faire. Ajouter les variables suivantes à votre classe:
Puis dans OnStart, vous faites quelque chose comme cela (j'ai une méthode d'assistance qui ne l'abattage dans cet exemple, et la "" la méthode le travail réel).:
Votre "Run" de la méthode, le travail du fil, ressemble à ceci (processInterval serait combien de temps vous voulez attendre entre les pistes, vous pouvez l'installer dans le constructeur ou simplement de coder en dur):
Puis dans OnStop, vous voulez faire cela:
Vous pouvez utiliser un objet de verrouillage pour empêcher le fil d'être arrêté tandis que votre travail se passe réellement...
Vous devez être prudent, si votre
ActualWorkDoneHere()
fonction prend trop de temps, windows signale le service de ne pas arrêter.Essayez d'utiliser un autoreset drapeau pour gérer l'arrêt du service. Dans ce cas, vous n'aurait pas à effectuer d'abandon de thread. Ont ajouté l'exemple de code ci-dessous
Cheers,
Bharath.
Mon service écoute sur une socket réseau, donc ce que j'ai fait est de créer un joint paire de sockets réseau, et a utilisé le système de sélection d'appel à écouter sur les deux. Si la paire rejoint déclaré prêt à le lire, je savais à l'arrêt du service.
Cette astuce peut être utilisée pour déclencher un nombre arbitraire de threads de s'arrêter aussi longtemps qu'aucun d'entre eux de lire à partir du couple.
Veuillez Essayer ceci à l'intérieur
onStop()