我如何在不使用睡眠的情况下执行C#中的短延迟?

我如何在不使用睡眠的情况下执行C#中的短延迟?,c#,timer,delay,sleep,C#,Timer,Delay,Sleep,我对编程非常陌生,到目前为止我已经学得很好了,我想,但是我仍然不能理解以我想要的方式进行延迟的想法。我正在做的是一种测试“游戏”的东西,使用一个Windows窗体应用程序,包括一个战斗系统。在它里面,我想做一个NPC,每隔几秒钟做一个动作。问题是,我还想让玩家在攻击之间进行交互。Thread.sleep对我来说似乎真的不起作用,不仅因为我不知道如何使用多线程,而且每当我尝试运行它时,比如说: textBox1.Text += "\r\nThread Sleeps!"; System.Thre

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

 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中所述

在您的示例中,您需要做的是:

  • 确保您的程序将.Net Framework 4.5作为目标框架
  • async
    关键字标记需要休眠的函数(参见下面的示例)
  • 使用System.Threading.Tasks添加
    到您的代码
  • 您的代码现在可以使用
    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);