我如何在不使用睡眠的情况下执行C#中的短延迟?
我对编程非常陌生,到目前为止我已经学得很好了,我想,但是我仍然不能理解以我想要的方式进行延迟的想法。我正在做的是一种测试“游戏”的东西,使用一个Windows窗体应用程序,包括一个战斗系统。在它里面,我想做一个NPC,每隔几秒钟做一个动作。问题是,我还想让玩家在攻击之间进行交互。Thread.sleep对我来说似乎真的不起作用,不仅因为我不知道如何使用多线程,而且每当我尝试运行它时,比如说:我如何在不使用睡眠的情况下执行C#中的短延迟?,c#,timer,delay,sleep,C#,Timer,Delay,Sleep,我对编程非常陌生,到目前为止我已经学得很好了,我想,但是我仍然不能理解以我想要的方式进行延迟的想法。我正在做的是一种测试“游戏”的东西,使用一个Windows窗体应用程序,包括一个战斗系统。在它里面,我想做一个NPC,每隔几秒钟做一个动作。问题是,我还想让玩家在攻击之间进行交互。Thread.sleep对我来说似乎真的不起作用,不仅因为我不知道如何使用多线程,而且每当我尝试运行它时,比如说: textBox1.Text += "\r\nThread Sleeps!"; System.Thre
textBox1.Text += "\r\nThread Sleeps!";
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
它似乎坚持先睡觉,然后打印两行
我想这就是我目前能说的,但如果这仍然太模糊或冗长,请随时告诉我
简言之,在C#中,我希望在运行前进行一些延迟,但同时仍允许用户交互。您可能可以使用计时器:
计时器可以为您提供高达1毫秒的精度。根据刻度间隔,将生成一个事件。在tick事件中执行您的操作。如果您使用的是.NET 4.5,则可以使用新的async/await框架睡眠,而无需锁定线程 它的工作原理是使用
async
关键字标记需要异步操作的函数。这只是对编译器的一个提示。然后在希望代码异步运行的行中使用wait
关键字,程序将在不锁定线程或UI的情况下等待。您调用的方法(在等待行上)也必须用async
关键字标记,并且通常命名为以async结尾,如ImportFilesAsync中所述
在您的示例中,您需要做的是:
async
关键字标记需要休眠的函数(参见下面的示例)代码>到您的代码
Task.Delay
方法而不是System.Threading.Thread.Sleep
方法(可以在Task.Delay上使用wait
,因为Task.Delay
在其定义中标记为async
)
在这里,您可以阅读更多关于和的信息。很抱歉,您唤醒了这样一个老问题。
但我认为原作者想要的答案是:
更改textbox1后,需要强制程序进行图形更新。您可以通过调用Update()代码>
通常,当线程完成时,这将自动完成。
例如,您按下一个按钮,对文本进行更改,线程死亡,然后触发.Update()
,您可以看到更改。
(我不是专家,所以我不能告诉你它是什么时候被解雇的,但无论如何它都与此类似。)
在这种情况下,您需要进行更改,暂停线程,然后再次更改文本,当线程最终停止时,将触发.Update()
。这导致您只能看到对文本所做的最后更改
如果在文本更改之间执行很长时间,您也会遇到同样的问题。private void WaitNSeconds(int秒)
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();
}
}
{
如果(秒<1)返回;
DateTime _desired=DateTime.Now.AddSeconds(秒);
while(DateTime.Now<\u所需){
睡眠(1);
System.Windows.Forms.Application.DoEvents();
}
}
通过使用System.Timer添加代码>对于您的程序,您可以使用此功能:
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(5000);
您可以改用计时器,并在您的时间间隔内启动它…线程还负责打印您的UI,但由于您使用Sleep
阻止它,因此它无法更新显示第一行的UI。请使用Task.Delay代替Sleep。这样,您就不会有任何被阻止的UI问题。这个新函数在.Net 4.5中可用。他/她问道-没有睡眠:)在wait
之后的所有代码都将异步运行,这是否正确?我用两个复选框做了一个例子,似乎是这样。@Black您只能在标记为async
的函数上使用await
,所以是-它将始终是异步的。但只有在await之后的部分?@Black是,只有在await关键字之后的部分
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(5000);