Thread.Sleep(1)在C#中的影响是什么?

在Windows窗体应用程序中调用Thread.Sleep(1)的影响是什么,如下面的代码所示:

 public Constructor() { Thread thread = new Thread(Task); thread.IsBackground = true; thread.Start(); } private void Task() { while (true) { // do something Thread.Sleep(1); } } 

这个线程会占用所有可用的CPU吗?

我可以使用哪些分析技术来衡量此线程的CPU使用率(除了任务pipe理器)?

如上所述,你的循环不会占用CPU。

但要小心 :Windows 不是一个实时的操作系统,所以你不会从Thread.Sleep(1)中获得每秒1000次唤醒。 如果你没有使用timeBeginPeriod来设置你的最小分辨率,你将会每隔15 ms唤醒一次。 即使将最小分辨率设置为1 ms,您仍然每3-4毫秒才会唤醒。

为了获得毫秒级定时器粒度,你必须使用Win32多媒体定时器( C#包装器 )。

不,它不会占用CPU,它会暂停你的线程至less这么长时间。 当线程暂停时,操作系统可以调度另一个不相关的线程来使用处理器。

Thread.Sleep(1)如上所述不会占用CPU。

以下是当一个线程睡眠(或多或less)时发生的情况:

  • Thread.Sleep被转换成一个系统调用,然后触发一个陷阱(一个允许操作系统控制的中断)
  • 操作系统检测到睡眠呼叫并将您的线程标记为已阻止。
  • 操作系统内部保存了需要唤醒的线程列表,以及何时发生。
  • 由于线程不再使用CPU的操作系统…
  • 如果父进程没有用完所有的时间片,操作系统将调度该进程的另一个线程执行。
  • 否则,另一个进程(或空闲进程)将开始执行。
  • 当时间到了,你的线程将被再次安排执行,这并不意味着它会自动开始执行。

最后一点,我不完全知道你在做什么,但是你似乎想要扮演调度器的angular色,就是睡觉,为CPU提供时间做其他事情…

在less数情况下(确实很less)可能是好的,但大多数情况下,您应该让调度人员完成工作,这可能比您知道得多 ,而且可以使工作比您做得更好

Bob Nadler提到Thread.Sleep(1)不保证1ms的睡眠时间。

以下是使用Win32多媒体计时器强制进入1ms睡眠的示例。

  [DllImport("winmm.dll")] internal static extern uint timeBeginPeriod(uint period); [DllImport("winmm.dll")] internal static extern uint timeEndPeriod(uint period); timeBeginPeriod(1); while(true) { Thread.Sleep(1); // will sleep 1ms every time } timeEndPeriod(1); 

在C#GUI应用程序中进行testing,发现应用程序使用了大约50%的CPU。

有关此主题的更多讨论,请参阅以下论坛主题:

http://www.dotnet247.com/247reference/msgs/57/289291.aspx

应该避免小的睡眠时间,因为放弃其时间片的线程在被重新发送时优先提升,并且这可能导致高的上下文切换。 在multithreading/服务器应用程序中,线程正在为CPU时间而战,这可能会导致抖动效应。 相反,依靠asynchronous函数和同步对象,如临界区或互斥/信号量。

这是一个古老的线索,出现在我的很多search,但Win7有一个新的调度程序,似乎行为不同于上述。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { DateTime dtEnd = DateTime.Now.AddSeconds(1.0); int i = 0; while (DateTime.Now < dtEnd) { i++; Thread.Sleep(1); } Console.WriteLine(i.ToString()); i = 0; long lStart = DateTime.Now.Ticks; while (i++ < 1000) Thread.Sleep(1); long lTmp = (DateTime.Now.Ticks - lStart) / 10000; Console.WriteLine(lTmp.ToString()); Console.Read(); } } } 

用上面的代码,我的第一个结果给了946.所以在1秒的时间里,使用1ms的睡眠,我得到了946唤醒。 这非常接近1ms。

第二部分询问需要多长时间以每个1ms进行1000次睡眠事件。 我得到了1034ms。 再次,近1ms。

这是使用.Net 4.0在1.8GHz的core2duo + Win7上

编辑:记住,睡眠(x)这个时候并不意味着醒来,这意味着不要早于这个时间唤醒我。 这是不能保证的。 虽然,可以增加线程的优先级,Windows应该在低优先级的线程之前安排线程。

不,它不会占用所有可用的CPU,因为当另一个线程有工作时,睡眠线程将被OS调度程序切换出来。

不,不会的 你几乎看不到它。 某个地方每秒钟less于1000次的时间,这个线程会在醒来之前再次进入hibernate状态。

编辑:

我必须检查。 在Java 1.5上运行,这个testing

 @Test public void testSpeed() throws InterruptedException { long currentTime = System.currentTimeMillis(); int i = 0; while (i < 1000) { Thread.sleep(1); i++; } System.out.println("Executed in " + (System.currentTimeMillis() - currentTime)); } 

在我的3ghz机器上每秒钟大约有500次睡眠。 我想C#应该是相当相同的。 我猜想有人会用这个非常重要的现实世界基准testing报告C#编号。 顺便说一下,没有可观察的CPU使用率。

一个线程一次最多可以支持一个(逻辑)CPU。 1ms的睡眠不会被占用。 不要stream汗

也看看这个: msdn论坛

 using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace Test { public static class Program { public static void Main(string[] args) { Stopwatch sw = new Stopwatch(); for (int i = 0; i < 10; ++i) { sw.Reset(); sw.Start(); Thread.Sleep(50); sw.Stop(); Console.WriteLine("(default) Slept for " + sw.ElapsedMilliseconds); TimeBeginPeriod(1); sw.Reset(); sw.Start(); Thread.Sleep(50); sw.Stop(); TimeEndPeriod(1); Console.WriteLine("(highres) Slept for " + sw.ElapsedMilliseconds + "\n"); } } [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); } }