如何让我的 C# 程序休眠 50 毫秒?

How do I get my C# program to sleep for 50 milliseconds?

提问人:TK. 提问时间:9/18/2008 最后编辑:Aryan BeezadhurTK. 更新时间:10/21/2023 访问量:472161

问:

如何让我的 C# 程序休眠(暂停执行)50 毫秒?

C# vb.net

评论

17赞 Joel Coehoorn 1/18/2010
如果我在 VB.Net 团队,我会加上;作为该语言下一个版本的注释字符......
8赞 BlueRaja - Danny Pflughoeft 4/8/2010
我认为 VB 程序员足够聪明,可以找出等价物。

答:

414赞 Isak Savo 9/18/2008 #1
System.Threading.Thread.Sleep(50);

但请记住,在主 GUI 线程中执行此操作会阻止您的 GUI 更新(它会感觉“缓慢”)

只需删除它即可使其也适用于 VB.net。;

评论

0赞 Jay Nirgudkar 4/28/2015
在方法中调用 sleep 后,程序会继续在后台执行(不创建新线程)吗?另外,如果我在新线程中调用 sleep,主线程会继续工作吗?
0赞 Isak Savo 5/28/2015
@JayNirgudkar,调用 Sleep 的线程将停止。其他线程不受影响。
1赞 Akumaburn 10/29/2016
这不能保证准确。
32赞 Alexander Prokofyev 9/18/2008 #2

使用此代码

using System.Threading;
// ...
Thread.Sleep(50);
14赞 SelvirK 9/18/2008 #3
Thread.Sleep(50);

操作系统不会计划在指定的时间内执行该线程。此方法更改线程的状态以包括 WaitSleepJoin。

此方法不执行标准的 COM 和 SendMessage 抽取。 如果需要在具有 STAThreadAttribute 的线程上休眠,但又要执行标准 COM 和 SendMessage 抽取,请考虑使用指定超时间隔的 Join 方法的重载之一。

Thread.Join
56赞 Joel Coehoorn 9/18/2008 #4

无法在 Windows 中指定确切的睡眠时间。为此,您需要一个实时操作系统。您能做的最好的事情就是指定最短睡眠时间。然后由调度程序来唤醒你的线程。并且永远不要调用 GUI 线程。.Sleep()

174赞 Marcel Toth 4/21/2011 #5

基本上有 3 种选择可以等待(几乎)任何编程语言:

  1. 松散的等待
    • 在给定时间内执行线程块(= 不消耗处理能力)
    • 无法对阻塞/等待的线程进行处理
    • 不那么精确
  2. 紧等待(也称为循环)
    • 处理器在整个等待间隔内非常繁忙(事实上,它通常消耗一个内核处理时间的 100%)
    • 某些操作可以在等待时执行
    • 非常精确
  3. 前 2 个的组合
    • 它通常结合了 1.和精确性 + 做某事的能力 2.

对于 1.- C# 中的松散等待:

Thread.Sleep(numberOfMilliseconds);

但是,Windows 线程调度程序导致精度约为 15 毫秒(因此睡眠可以轻松等待 20 毫秒,即使计划仅等待 1 毫秒)。Sleep()

对于 2.- C# 中的等待时间很紧:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do possible
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
}

我们也可以使用或其他时间测量方法,但速度要快得多(这在紧密循环中确实会变得可见)。DateTime.NowStopwatch

对于 3.-组合:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do STILL POSSIBLE
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
    Thread.Sleep(1); //so processor can rest for a while
}

此代码会定期阻塞线程 1 毫秒(或稍长,具体取决于操作系统线程调度),因此处理器在阻塞时间内不会繁忙,并且代码不会消耗 100% 的处理器功率。其他处理仍然可以在阻止之间执行(例如:更新 UI、处理事件或进行交互/通信)。

评论

3赞 JonnyRaa 5/18/2015
计时器也可能引起人们的兴趣
55赞 Toni Petrina 12/3/2012 #6

由于现在您拥有 async/await 功能,因此休眠 50 毫秒的最佳方法是使用 Task.Delay:

async void foo()
{
    // something
    await Task.Delay(50);
}

或者,如果面向 .NET 4(使用 VS2010 的异步 CTP 3 或 Microsoft.Bcl.Async),则必须使用:

async void foo()
{
    // something
    await TaskEx.Delay(50);
}

这样你就不会阻塞 UI 线程。

评论

0赞 Teoman shipahi 12/27/2013
如果它处于循环中,您可以在此延迟期间响应.flush吗?
0赞 Toni Petrina 12/27/2013
不可以。我相信有一个版本。FlushAsync
9赞 stuartd 12/29/2013
一种不需要声明的替代方法是调用asyncTask.Delay(50).Wait();
0赞 Craig 4/13/2023
由于阻塞异步操作时可能存在死锁,因此应格外小心地遵循使用建议。Wait
8赞 Colonel Panic 3/27/2013 #7

为了便于阅读:

using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));
-2赞 Akumaburn 10/29/2016 #8

两全其美:

using System.Runtime.InteropServices;

    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
    private static extern uint TimeBeginPeriod(uint uMilliseconds);

    [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
    private static extern uint TimeEndPeriod(uint uMilliseconds);
    /**
     * Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
     */
    private void accurateSleep(int milliseconds)
    {
        //Increase timer resolution from 20 miliseconds to 1 milisecond
        TimeBeginPeriod(1);
        Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
        stopwatch.Start();

        while (stopwatch.ElapsedMilliseconds < milliseconds)
        {
            //So we don't burn cpu cycles
            if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
            {
                Thread.Sleep(5);
            }
            else
            {
                Thread.Sleep(1);
            }
        }

        stopwatch.Stop();
        //Set it back to normal.
        TimeEndPeriod(1);
    }
1赞 timmebee 8/6/2019 #9

从 .NET Framework 4.5 开始,可以使用:

using System.Threading.Tasks;

Task.Delay(50).Wait();   // wait 50ms

评论

1赞 GSerg 8/17/2021
发布于 6 年前
0赞 Craig 4/13/2023
阻止异步操作具有潜在危险,并可能导致死锁。使用时要格外小心。
0赞 Eishwar patley 10/21/2023 #10

在 C# 中,可以使用 Thread.Sleep 方法或 Task.Delay 使程序暂停指定的毫秒数。以下是如何执行此操作的示例:

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // Sleep for 50 milliseconds
        Thread.Sleep(50);
    Console.WriteLine("Sleep for 50 milliseconds");
    }
}

使用 Task.Delay(异步方法):

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // Sleep for 50 milliseconds asynchronously
        await Task.Delay(50);
        
        // pause for 50 milliseconds and then continue execution.
        Console.WriteLine("resumed after sleeping for 50 ms.");
    }
}