33

我对编程非常陌生,我认为到目前为止我的学习已经足够好,但我仍然无法理解以我想要的方式进行延迟的想法。我正在做的是一种使用涉及战斗系统的 Windows 窗体应用程序的测试“游戏”。在其中,我想制作一个每隔几秒钟执行一次动作的 NPC。问题是,我还想让玩家在攻击之间进行交互。Thread.sleep 似乎真的对我不起作用,不仅因为我不知道如何多线程,而且每当我尝试运行它时,比如说,像这样:

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

它似乎坚持先睡觉,然后打印两行。

我想这就是我目前所能说的,但如果这仍然太模糊或冗长,请随时告诉我。

简而言之,在 C# 中,我想在运行之前做一些延迟,但同时仍然允许用户交互。

4

5 回答 5

66

如果您使用的是 .NET 4.5,您可以使用新的 async/await 框架来休眠,而无需锁定线程。

它的工作原理是使用async关键字标记需要异步操作的函数。这只是对编译器的提示。然后await在您希望代码异步运行的行上使用关键字,您的程序将等待而不锁定线程或 UI。您调用的方法(在 await 行上)也必须用async关键字标记,并且通常以 Async 结尾,如ImportFilesAsync中所示。

您在示例中需要做的是:

  1. 确保您的程序将.Net Framework 4.5作为目标框架
  2. async使用关键字标记需要休眠的函数(参见下面的示例)
  3. 添加using System.Threading.Tasks;到您的代码中。

您的代码现在可以使用Task.Delay方法而不是System.Threading.Thread.Sleep方法(可以使用awaiton,Task.Delay因为在其定义Task.Delay中标记为)。async

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

在这里你可以阅读更多关于Task.DelayAwait的信息。

于 2013-08-22T07:39:25.777 回答
7

通过添加using System.Timers;到您的程序中,您可以使用此功能:

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);
于 2017-08-03T19:35:18.653 回答
4

很抱歉唤醒了这样一个老问题。但我认为原作者想要的答案是:

在对 textbox1 进行更改后,您需要强制程序进行图形更新。你可以通过调用来做到这一点Update();

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

通常这将在线程完成时自动完成。例如,您按下一个按钮,对文本进行更改,线程终止,然后.Update()被触发,您会看到更改。(我不是专家,所以我不能真正告诉你它何时被解雇,但无论如何它都与此类似。)

在这种情况下,您进行更改,暂停线程,然后再次更改文本,当线程最终死亡时,.Update()将触发。这导致您只能看到对文本所做的最后一次更改。

如果在文本更改之间执行很长时间,您将遇到同样的问题。

于 2015-07-12T11:39:48.990 回答
1

您可能可以使用计时器:http: //msdn.microsoft.com/en-us/library/system.timers.timer.aspx

计时器可以为您提供高达 1 毫秒的精度。根据滴答间隔,将生成一个事件。在滴答事件中做你的事情。

于 2013-08-22T05:50:15.513 回答
-2
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();
    }
}
于 2017-07-19T11:28:56.827 回答