问题
I'm incredibly new to programming, and I've been learning well enough so far, I think, but I still can't get a grasp around the idea of making a delay the way I want. What I'm working on is a sort of test "game" thingy using a Windows forms application that involves a combat system. In it, I want to make an NPC that does an action every couple of seconds. The problem is, I also want to allow the player to interact between attacks. Thread.sleep really doesn't seem to work for me not only because I don't know how to multithread, but whenever I try to run it, say, like this:
textBox1.Text += "\r\nThread Sleeps!";
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
It seems to insist on sleeping first, then printing both lines.
I think that's all I can say at the moment, but if that's still too vague or wordy, feel free to tell me.
In short, In C# I want to make something delay before running but at the same time still allow user interaction.
回答1:
If you're using .NET 4.5 you can use the new async/await framework to sleep without locking the thread.
How it works is that you mark the function in need of asynchronous operations, with the async
keyword. This is just a hint to the compiler. Then you use the await
keyword on the line where you want your code to run asynchronously and your program will wait without locking the thread or the UI. The method you call (on the await line) has to be marked with an async
keyword as well and is usually named ending with Async, as in ImportFilesAsync.
What you need to do in your example is:
- Make sure your program has .Net Framework 4.5 as Target Framework
- Mark your function that needs to sleep with the
async
keyword (see example below) - Add
using System.Threading.Tasks;
to your code.
Your code is now ready to use the Task.Delay
method instead of the System.Threading.Thread.Sleep
method (it is possible to use await
on Task.Delay
because Task.Delay
is marked with async
in its definition).
private async void button1_Click(object sender, EventArgs e)
{
textBox1.Text += "\r\nThread Sleeps!";
await Task.Delay(3000);
textBox1.Text += "\r\nThread awakens!";
}
Here you can read more about Task.Delay and Await.
回答2:
Sorry for awakening an old question like this. But I think what the original author wanted as an answer was:
You need to force your program to make the graphic update after you make the change to the textbox1. You can do that by invoking Update();
textBox1.Text += "\r\nThread Sleeps!";
textBox1.Update();
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
textBox1.Update();
Normally this will be done automatically when the thread is done.
Ex, you press a button, changes are made to the text, thread dies, and then .Update()
is fired and you see the changes.
(I'm not an expert so I cant really tell you when its fired, but its something similar to this any way.)
In this case, you make a change, pause the thread, and then change the text again, and when the thread finally dies the .Update()
is fired. This resulting in you only seeing the last change made to the text.
You would experience the same issue if you had a long execution between the text changes.
回答3:
By adding using System.Timers;
to your program you can use this function:
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) { };
}
Delay is a function and can be used like:
delay(5000);
回答4:
You can probably use timers : http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Timers can provide you a precision up to 1 millisecond. Depending on the tick interval an event will be generated. Do your stuff inside the tick event.
回答5:
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();
}
}
来源:https://stackoverflow.com/questions/18372355/how-can-i-perform-a-short-delay-in-c-sharp-without-using-sleep