Comment puis-je effectuer un court délai en C# sans utiliser le sommeil?

je suis incroyablement nouveau dans la programmation, et j'ai assez bien appris jusqu'à présent, je pense, mais je ne peux toujours pas comprendre l'idée de faire un retard comme je veux. Ce sur quoi je travaille est une sorte de test "jeu" Machin en utilisant une application Windows forms qui implique un système de combat. Je veux faire un NPC qui fait une action toutes les deux secondes. Le problème est, je veux aussi permettre au joueur d'interagir entre les attaques. Fil.le sommeil n'a vraiment pas l'air de fonctionner pour moi de ne pas seulement parce que je ne sais pas comment faire du multithread, mais chaque fois que j'essaie de le lancer, dites, comme ceci:

 textBox1.Text += "rnThread Sleeps!";
 System.Threading.Thread.Sleep(4000);
 textBox1.Text += "rnThread awakens!";

il semble insister pour dormir d'abord, puis imprimer les deux lignes.

je pense que c'est tout ce que je peux dire pour le moment, mais si c'est encore trop vague ou verbeux, n'hésitez pas à me le dire.

En bref, En C# je veux faire quelque chose de délai avant l'exécution, mais en même temps permettre l'interaction de l'utilisateur.

20
demandé sur user2706003 2013-08-22 09:34:35

5 réponses

si vous utilisez .NET 4.5 vous pouvez utiliser le nouveau framework async/Wait pour dormir sans verrouiller le thread.

Comment cela fonctionne est que vous marquez la fonction dans le besoin d'opérations asynchrones, avec l' async mot clé. C'est juste un indice pour le compilateur. Ensuite, vous utilisez le await mot-clé sur la ligne où vous voulez que votre code s'exécute asynchrone et votre programme attendra sans verrouiller le thread ou L'interface utilisateur. La méthode que vous appelez (sur la ligne d'attente) doit être marquée avec async mot-clé aussi bien et est habituellement nommé se terminant par Async, comme dans ImportFilesAsync.

Ce que vous devez faire dans votre exemple:

  1. assurez-vous que votre programme a .Net Framework 4.5 Cadre Cible
  2. marquez votre fonction qui a besoin de dormir avec le async mot-clé (voir l'exemple ci-dessous)
  3. Ajouter using System.Threading.Tasks; à votre code.

Votre code est maintenant prêt pour utiliser le Task.Delay méthode au lieu de l' System.Threading.Thread.Sleep méthode (il est possible d'utiliser awaitTask.Delay parce que Task.Delay marqué avec async dans sa définition).

private async void button1_Click(object sender, EventArgs e)
{
    textBox1.Text += "\r\nThread Sleeps!";
    await Task.Delay(3000);
    textBox1.Text += "\r\nThread awakens!";
}

ici vous pouvez en savoir plus sur Tâche.Retard et attendez.

50
répondu Ohlin 2018-07-12 20:32:12

désolé de réveiller une vieille question comme celle-ci. Mais je pense que l'auteur voulait que la réponse a été:

vous devez forcer votre programme à faire la mise à jour graphique après avoir fait le changement à la textbox1. Vous pouvez le faire en invoquant Update();

textBox1.Text += "\r\nThread Sleeps!";
textBox1.Update();
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
textBox1.Update();

Normalement, ce sera fait automatiquement lorsque le thread est terminé. Ex, vous appuyez sur un bouton, des changements sont faits au texte, le fil meurt, et puis .Update() est viré et vous voyez les changements. (Je ne suis pas un expert donc je ne peux pas vraiment vous dire quand il a tiré, mais c'est quelque chose de similaire à cela d'une façon ou d'une autre.)

dans ce cas, vous faites un changement, mettez le thread en pause, puis changez le texte à nouveau, et quand le thread meurt enfin le .Update() est déclenché. Vous ne voyez donc que la dernière modification apportée au texte.

vous éprouveriez le même problème si vous aviez une longue exécution entre les changements de texte.

4
répondu Tomas Frid 2017-03-01 15:50:40

En ajoutant using System.Timers; pour votre programme, vous pouvez utiliser cette fonction:

private static void delay(int Time_delay)
{
   int i=0;
  //  ameTir = new System.Timers.Timer();
    _delayTimer = new System.Timers.Timer();
    _delayTimer.Interval = Time_delay;
    _delayTimer.AutoReset = false; //so that it only calls the method once
    _delayTimer.Elapsed += (s, args) => i = 1;
    _delayTimer.Start();
    while (i == 0) { };
}

Délai est fonction et peut être utilisé comme:

delay(5000);
2
répondu user8413784 2017-08-03 20:15:42

Vous pouvez probablement utiliser les minuteries : http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

Minuteries peuvent vous fournir une précision jusqu'à 1 milliseconde. Selon la tique intervalle d'un événement est généré. Faites vos trucs dans l'évènement tick.

1
répondu Abhishek Shetty 2013-08-22 05:50:15
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();
    }
}
0
répondu Khalid 2017-07-19 11:28:56