8
votes

Quelle est la meilleure façon d'attendre un certain temps (dire 10 secondes) en C #?

Je veux attendre 15 secondes, alors le contrôle devrait reprendre de la déclaration suivante.

Je n'ai rien d'autre à faire en attendant (attendant simplement).

Je sais que Il y a thread.sleep (15000) . Ce que je ne sais pas, c'est la meilleure méthode d'attente? Quelles sont les limites de ceci?

Le code serait comme celui-ci: xxx

c#

2 commentaires

Thread.sleep (15000) est bien pour C #. Pour Winforms, WPF ou ASP.NET, c'est une catastrophe.


Proche-duplicats: Stackoverflow.com/questions/1091710 , Stackoverflow.com/questions/407130 , Stackoverflow.com/Questtions/1208103 et Stackoverflow.com/questions/903688 .


8 Réponses :


2
votes

Vous pouvez toujours utiliser une minuterie, puis exécuter du code après la durée définie. Toutefois, si vous n'avez rien à faire et que vous voulez juste attendre à un point particulier dans le code, je pense que thread.sleep (150000); est suffisant. [EDIT: orthographe]


0 commentaires

3
votes

thread.sleep semble une chose sensible à faire s'il n'y a rien d'autre à faire en attendant. Il met le fil à dormir pendant cette période afin qu'il n'utilise aucune ressource CPU.


2 commentaires

Oui, toute autre méthode utiliserait la CPU et vous ne voulez pas que si tout ce que vous avez à faire, c'est attendre ...


Il est particulièrement utile dans les tests unitaires où vous devez simuler le temps Delta. La méthode ne peut pas quitter si thread.sleep () est moins mal dans cette situation particulière. Pour les intervalles de longue date, je me suis trompé en modifiant le temps système. Comme si vous posez l'ordinateur dans une machine à temps. Lorsque le test est effectué, il redevient le temps système à la normale.



12
votes

L'inconvénient du thread.sleep est si cela est appelé dans votre fil d'interface graphique (le fil qui traite des événements de l'interface graphique, par exemple une méthode du gestionnaire de bouton, ou une méthode appelée à partir d'une touche, cliquez sur le gestionnaire, etc.). L'application semblera geler et être déroulante pour ces 15 secondes.

Ce serait parfaitement bien si vous aviez expliqué un fil séparé et appelé thread.sleep, en supposant que cela ne vous dérange pas que le fil ne faisait rien pendant 15 secondes.

L'alternative serait de créer une minuterie et de commencer après la STMT 2, et placez STMT 3 dans le gestionnaire d'événements de tick pour la minuterie et arrêtez également la minuterie dans ce gestionnaire.


0 commentaires

7
votes

Cela peut ne pas être une réponse directe à votre question. Je dirais vérifier si votre flux de processus est meilleur que de vérifier si le code est meilleur; -)

attendez-vous pendant 15 secondes pour vous assurer que STMT2; est complet? Si oui, ajoutez un gestionnaire, dès que STMNT 2 est exécuté, constituerait une meilleure solution (?)

Vous pouvez également utiliser une minuterie pour attendre. thread.sleep est un mauvais design. Nous avons une question similaire qui parle de comparaison avec thread.sleep et minuterie .


0 commentaires

1
votes

Si vous voulez toujours attendre un délai donné, alors dormir est utile. De toute évidence, vous ne devriez pas faire cela sur un fil où les réponses opportunes sont attendues.

Gardez à l'esprit que votre fil dormira pendant toute la durée. Si, pour une raison quelconque, vous voulez que le fil reprenne plus tôt, vous ferez mieux d'utiliser la signalisation ou les rappel. En utilisant l'une d'entre elles au lieu de dormez , vous minimiserez le temps d'attente inutile.


0 commentaires

3
votes

Essayez quelque chose comme ce qui suit:

void Method()
{
    console.log('statement 1');
    console.log('statement 2');

    var timer = new System.Threading.Timer(
        o =>   // timer callback
        {
           console.log('statement 2');
        },
        15000, // Delay
        0      // Repeat-interval; 0 for no repeat
    );
}


4 commentaires

Il y a un problème avec cet exemple. Cela ne fonctionnera pas de manière fiable, car aucune référence à l'objet (code> est conservée n'importe où. Ainsi, il est soumis à la collecte des ordures. Plus votre retard est long, plus cela sera probablement un problème. De MSDN: Tant que vous utilisez une minuterie, vous devez conserver une référence. Comme avec n'importe quel objet géré, une minuterie est soumise à la collecte des ordures lorsqu'il n'y a aucune référence. Le fait qu'une minuterie soit toujours active ne l'empêche pas d'être collectée.


@Thorarin: Ah, bon point. J'ai tout oublié de ce petit fait. Je verrai si je peux corriger l'exemple.


Si vous souhaitez expédier le rappel sur le thread d'interface utilisateur, vous devez utiliser system.windows.forms.ticer à la place.


STMT1 ne compilera pas. Est-ce un mot clé C #?



-1
votes

Je ne sais pas 100%, mais si vous avez vraiment besoin de votre méthode pour revenir après 15 secondes, essayez de suivre:


Method()
{
   stmt1();
   stmt2();

   int time = DateTime.Now.Millisecond;
   while (15*1000 > DateTime.Now.Millisecond - time)
   {
       Thread.Sleep(10)
       Application.DoEvents();
   }
   stmt3();
}


0 commentaires

1
votes
void Method()
{
    Statement1();
    Statement2();

    // Start the timer for a single 15 second shot.
    // Keep a reference to it (Mytimer) so that the timer doesn't get collected as garbage
    Mytimer = new System.Threading.Timer((a) =>
        {
            // Invoke the 3rd statement on the GUI thread
            BeginInvoke(new Action(()=>{ Statement3(); }));
        }, 
    null,
    15000, // 15 seconds
    System.Threading.Timeout.Infinite); // No repeat
}

0 commentaires