如何使我的C#程序睡眠50毫秒?

时间:2008-09-18 09:11:50

标签: c# vb.net

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

这似乎是一个简单的问题,但我有一个暂时的大脑失败时刻!

10 个答案:

答案 0 :(得分:308)

System.Threading.Thread.Sleep(50);

请记住,在主GUI线程中执行此操作会阻止GUI更新(它会感觉“迟钝”)

只需移除;即可使其适用于VB.net。

答案 1 :(得分:146)

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

  1. 等待轻松
    • 执行线程块给定时间(=不消耗处理能力)
    • 阻止/等待线程无法处理
    • 不太精确
  2. 紧迫等待(也称为紧密循环)
    • 处理器在整个等待间隔内非常繁忙(事实上,它通常占用一个核心处理时间的100%)。
    • 等待时可执行某些操作
    • 非常精确
  3. 之前2的
  4. 组合
    • 它通常结合了处理效率1.和精确度+能力做2的事情。

  5. 表示1. - 在C#中等待轻松:

    Thread.Sleep(numberOfMilliseconds);
    

    然而,Windows线程调度程序导致Sleep()的准确度大约为15ms(因此,即使计划等待1ms,Sleep也可以轻松等待20ms)。

    表示2. - 在C#中等待是:

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

    我们也可以使用DateTime.Now或其他时间测量方法,但Stopwatch要快得多(这会在紧密循环中变得明显)。

    表示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
    }
    

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

答案 2 :(得分:54)

您无法在Windows中指定完全的休眠时间。你需要一个实时操作系统。您可以做的最好的事情是指定最小睡眠时间。然后由调度程序在此之后唤醒您的线程。并且从不在GUI线程上调用.Sleep()

答案 3 :(得分:44)

从现在开始你有async / await功能,睡眠50ms的最佳方法是使用Task.Delay:

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

或者,如果您的目标是.NET 4(使用Async CTP 3 for VS2010或Microsoft.Bcl.Async),则必须使用:

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

这样您就不会阻止UI线程。

答案 4 :(得分:31)

使用此代码

using System.Threading;
// ...
Thread.Sleep(50);

答案 5 :(得分:14)

Thread.Sleep(50);

在指定的时间内,操作系统不会安排线程执行。此方法将线程的状态更改为包括WaitSleepJoin。

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

Thread.Join

答案 6 :(得分:10)

Thread.Sleep

答案 7 :(得分:3)

为了便于阅读:

using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));

答案 8 :(得分:0)

两全其美:

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);
    }

答案 9 :(得分:0)

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

using System.Threading.Tasks;

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