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

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

438108 次浏览
System.Threading.Thread.Sleep(50);

记住,在主GUI线程中这样做会阻碍GUI的更新(它会感觉“迟缓”)。

只需删除;,使它也适用于VB.net。

使用这段代码

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

在指定的时间内,操作系统不会调度线程执行。该方法将线程的状态更改为包含WaitSleepJoin。

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

Thread.Join

在Windows中不能指定确切的睡眠时间。你需要一个实时的操作系统。最好的方法是指定最低睡眠时间。然后由调度器在此之后唤醒线程。并且从来没有在GUI线程上调用.Sleep()

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

  1. < >强松散的等待
    • 在给定时间内执行线程块(=不消耗处理能力)
    • 在阻塞/等待线程上不可能进行任何处理
    • 不那么精确
    • 李< / ul > < / >
    • 紧张的等待(也称为紧循环)
      • 处理器在整个等待时间间隔内都非常繁忙(实际上,它通常会消耗一个核心100%的处理时间)
      • 有些操作可以在等待时执行
      • 非常精确的
      • 李< / ul > < / >
      • 结合 of previous 2
        • 它通常组合处理效率为1。严谨度+做事能力等于2。
        • 李< / ul > < / >

为1。c#中的松散等待:

Thread.Sleep(numberOfMilliseconds);

然而,windows线程调度器导致Sleep()的精度在15ms左右(因此Sleep可以轻松地等待20ms,即使计划只等待1ms)。

为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,处理事件或做交互/通信之类的事情)。

既然现在你有了async/await特性,那么最好的睡眠50ms的方法就是使用Task。延迟:

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

或者如果你的目标是。net 4(使用VS2010的Async CTP 3或Microsoft.Bcl.Async),你必须使用:

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

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

可读性:

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

两全其美:

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

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

using System.Threading.Tasks;


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