Attendre quelques secondes sans bloquer L'exécution de L'interface utilisateur
je voudrais attendre quelques secondes entre deux instructions, mais sans bloquer l'exécution.
par exemple, Thread.Sleep(2000)
ce n'est pas bon, parce qu'il bloque l'exécution.
l'idée est que j'appelle une méthode et puis j'attends X secondes (20 par exemple) en écoutant un événement venir. A la fin des 20 secondes je devrais faire une opération en fonction de ce qui s'est passé dans les 20 secondes.
7 réponses
je pense que ce que vous recherchez est une tâche.Retard. Cela ne bloque pas le thread comme le fait Sleep et cela signifie que vous pouvez le faire en utilisant un seul thread en utilisant le modèle de programmation async.
async Task PutTaskDelay()
{
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e)
{
await PutTaskDelay();
MessageBox.Show("I am back");
}
j'utilise:
private void WaitNSeconds(int segundos)
{
if (segundos < 1) return;
DateTime _desired = DateTime.Now.AddSeconds(segundos);
while (DateTime.Now < _desired) {
System.Windows.Forms.Application.DoEvents();
}
}
c'est un bon cas pour l'utilisation d'un autre fil:
// Call some method
this.Method();
Task.Factory.StartNew(() =>
{
Thread.Sleep(20000);
// Do things here.
// NOTE: You may need to invoke this to your main thread depending on what you're doing
});
le code ci-dessus attend .NET 4.0 ou au-dessus, sinon essayez:
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
Thread.Sleep(20000);
// Do things here
}));
la solution D'Omar est décente* si vous ne pouvez pas mettre à jour votre environnement à .NET 4.5 afin d'accéder à l'async et d'attendre les API. Cela dit, il y a ici un changement important qui devrait être fait afin d'éviter une mauvaise performance. Un léger délai doit être ajouté entre les appels à L'Application.DoEvents () afin d'éviter une utilisation excessive de CPU. En ajoutant
Thread.Sleep(1);
avant l'appel à Candidature.DoEvents (), vous pouvez ajouter un tel delay (1 milliseconde) et d'empêcher l'application d'utiliser tous les cycles cpu à sa disposition.
private void WaitNSeconds(int seconds)
{
if (seconds < 1) return;
DateTime _desired = DateTime.Now.AddSeconds(seconds);
while (DateTime.Now < _desired) {
Thread.Sleep(1);
System.Windows.Forms.Application.DoEvents();
}
}
*Voir la section https://blog.codinghorror.com/is-doevents-evil/ pour une discussion plus détaillée sur les écueils de l'utilisation de l'Application.DoEvents ().
Si vous ne souhaitez pas bloquer les choses et aussi voulez pas utiliser le multi-threading, voici la solution pour vous: https://msdn.microsoft.com/en-us/library/system.timers.timer (v=V110).aspx
le Thread de L'interface utilisateur n'est pas bloqué et la minuterie attend 2 secondes avant de faire quelque chose.
voici le code provenant du lien ci-dessus:
// Create a timer with a two second interval.
aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program... ");
Console.ReadLine();
Console.WriteLine("Terminating the application...");
je vous déconseille vraiment d'utiliser Thread.Sleep(2000)
, pour plusieurs raisons (quelques-unes sont décrites ici ), mais surtout parce que ce n'est pas utile quand il s'agit de débogage/test.
je recommande d'utiliser un C# Timer au lieu de Thread.Sleep()
. Timers vous permettent d'effectuer des méthodes fréquemment (si nécessaire) et sont beaucoup plus facile à utiliser dans les essais! Il y a un très bel exemple d'utilisation d'une minuterie juste derrière le hyperlink - mettez juste votre logique "ce qui se passe après 2 secondes" dans la méthode Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
.