如何让我的C#程序睡眠50毫秒?
我如何让我的C#程序睡眠50毫秒?
这似乎是一个容易的问题,但我暂时脑力衰竭的一瞬间!
System.Threading.Thread.Sleep(50);
请记住,在主要的GUI线程中这样做会阻止你的GUI更新(它会觉得“呆滞”)
只要删除;
以使其工作VB.net以及。
(几乎)任何编程语言基本上有三种select:
- 松开等待
- 在给定时间执行线程块(=不消耗处理能力)
- 阻塞/等待线程无法处理
- 不太精确
- 紧张的等待 (也叫紧圈)
- 处理器在整个等待间隔内非常繁忙(实际上,它通常消耗一个内核处理时间的100%),
- 一些动作可以在等待的时候执行
- 非常精确
- 以前2的组合
- 它通常结合了1的处理效率和精确度+做一些2的能力。
为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,处理事件或进行交互/通信等)。
您无法在Windows中指定确切的睡眠时间。 你需要一个实时的操作系统。 你可以做的最好的是指定一个最小的睡眠时间。 然后由调度程序在此之后唤醒线程。 不要在GUI线程上调用.Sleep()
。
由于现在你有asynchronous/等待function,50毫秒睡眠的最佳方法是使用Task.Delay:
async void foo() { // something await Task.Delay(50); }
或者,如果您的目标是.NET 4(针对VS2010或Microsoft.Bcl.Async的asynchronousCTP 3),则必须使用:
async void foo() { // something await TaskEx.Delay(50); }
这样你就不会阻塞UI线程。
使用这个代码
using System.Threading; // ... Thread.Sleep(50);
Thread.Sleep(50);
该线程不会被计划在指定的时间内被操作系统执行。 此方法将线程的状态更改为包含WaitSleepJoin。
此方法不执行标准的COM和SendMessage泵。 如果您需要在具有STAThreadAttribute的线程上hibernate,但要执行标准的COM和SendMessage抽取,请考虑使用指定超时间隔的Join方法的重载之一。
Thread.Join
Thread.Sleep
为了便于阅读:
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); }