提问人:TK. 提问时间:9/18/2008 最后编辑:Aryan BeezadhurTK. 更新时间:10/21/2023 访问量:472161
如何让我的 C# 程序休眠 50 毫秒?
How do I get my C# program to sleep for 50 milliseconds?
答:
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 方法的重载之一。
Thread.Join
无法在 Windows 中指定确切的睡眠时间。为此,您需要一个实时操作系统。您能做的最好的事情就是指定最短睡眠时间。然后由调度程序来唤醒你的线程。并且永远不要调用 GUI 线程。.Sleep()
基本上有 3 种选择可以等待(几乎)任何编程语言:
- 松散的等待
- 在给定时间内执行线程块(= 不消耗处理能力)
- 无法对阻塞/等待的线程进行处理
- 不那么精确
- 紧等待(也称为紧循环)
- 处理器在整个等待间隔内非常繁忙(事实上,它通常消耗一个内核处理时间的 100%)
- 某些操作可以在等待时执行
- 非常精确
- 前 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.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
}
此代码会定期阻塞线程 1 毫秒(或稍长,具体取决于操作系统线程调度),因此处理器在阻塞时间内不会繁忙,并且代码不会消耗 100% 的处理器功率。其他处理仍然可以在阻止之间执行(例如:更新 UI、处理事件或进行交互/通信)。
评论
由于现在您拥有 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 线程。
评论
FlushAsync
async
Task.Delay(50).Wait();
Wait
为了便于阅读:
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
在 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.");
}
}
评论