J'ai une unité de travail que je fais dans un fil (pas le fil principal). Dans certaines circonstances, je voudrais mettre ce fil en veille pendant 10 secondes. Thread.Sleep (10000) est-il le moyen le plus économe en ressources de le faire?
Thread.Sleep (10000) est-il le moyen le plus économe en ressources de le faire?
Oui dans le sens où il ne s'agit pas d'attendre, mais d'abandonner le processeur.
Mais cela gaspille un fil. Vous ne devriez pas adapter cela à de nombreux threads endormis.
Comme personne d'autre n'en a parlé ...
Si vous voulez qu'un autre thread puisse réveiller votre thread "en sommeil", vous pouvez aussi utiliser Monitor.Wait
au lieu de Thread.Sleep
:
private readonly object sharedMonitor;
private bool shouldStop;
public void Stop()
{
lock (sharedMonitor)
{
shouldStop = true;
Monitor.Pulse(sharedMonitor);
}
}
public void Loop()
{
while (true)
{
// Do some work...
lock (sharedMonitor)
{
if (shouldStop)
{
return;
}
Monitor.Wait(sharedMonitor, 10000);
if (shouldStop)
{
return;
}
}
}
}
Notez que nous n’accédons qu’à shouldStop
dans le verrou, il n’ya donc pas de problème de modèle de mémoire.
Vous voudrez peut-être attendre jusqu'à ce que vous dormiez vraiment 10 secondes, au cas où vous auriez des réveils parasites - cela dépend de l’importance que vous ne faites pas faire le travail à nouveau pendant 10 autres secondes. (Je n'ai jamais rencontré sciemment de sifflements parasites, mais je crois qu'ils sont possibles.)
Prenez l'habitude d'utiliser Thread.CurrentThread.Join (timeout) au lieu de Thread.Sleep.
La différence est que Join fera toujours du pompage de messages (par exemple, GUI & COM).
La plupart du temps, cela n'a pas d'importance, mais cela facilite la vie si vous devez utiliser un objet COM ou une interface graphique dans votre application.
De l'efficacité des ressources, oui.
Pour la conception, cela dépend des circonstances pour la pause. Vous voulez que votre travail soit autonome, donc si le thread doit suspendre parce qu'il sait attendre, mettez-le en pause dans le code du thread à l'aide de la méthode statique Thread.Sleep. Si la pause se produit en raison d'un événement externe autre que celui dont vous avez besoin pour contrôler le traitement du thread, demandez au propriétaire du thread de garder une référence au thread et appelez childThread.Sleep.
Oui. Il n'y a pas d'autre moyen efficace ou sûr de dormir le fil.
Toutefois, si vous travaillez en boucle, vous pouvez utiliser la boucle Veille pour faciliter l’abandon du fil au cas où vous souhaiteriez annuler votre travail.
Voici un exemple:
bool exit = false;
...
void MyThread()
{
while(!exit)
{
// do your stuff here...
stuff...
// sleep for 10 seconds
int sc = 0;
while(sc < 1000 && !exit) { Thread.Sleep(10); sc++; }
}
}
Cela traitera quelque chose toutes les x secondes sans utiliser de thread Vous ne savez pas comment ne pas utiliser votre propre thread se compare à une tâche à exécuter créée toutes les deux secondes
public void LogProcessor()
{
if (_isRunning)
{
WriteNewLogsToDisk();
// Come back in 2 seonds
var t = Task.Run(async delegate
{
await Task.Delay(2000);
LogProcessor();
});
}
}