web-dev-qa-db-fra.com

Mettre le thread actuel en veille

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?

13
Hosea146

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.

21
Henk Holterman

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.)

13
Jon Skeet

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.

6
adrianm

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.

0
Steve

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++; }
    }
}
0
Polynomial

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();
            });               
        }
    }
0
IvoTops