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.
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:
- assurez-vous que votre programme a .Net Framework 4.5 Cadre Cible
- marquez votre fonction qui a besoin de dormir avec le
async
mot-clé (voir l'exemple ci-dessous) - 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 await
Task.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.
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.
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);
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.
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();
}
}