Thread.Sleep小于1毫秒

我想用小于1毫秒的时间调用线程hibernate。 我读到没有thread.Sleep也没有Windows-OS支持。

那是什么解决方案?

对于所有想知道我为什么需要这个的人:我正在进行压力测试,并想知道我的模块每秒可以处理多少消息。 所以我的代码是:

// Set the relative part of Second hat will be allocated for each message //For example: 5 messages - every message will get 200 miliseconds var quantum = 1000 / numOfMessages; for (var i = 0; i < numOfMessages; i++) { _bus.Publish(new MyMessage()); if (rate != 0) Thread.Sleep(quantum); } 

我很高兴得到你的意见。

你不能这样做。 单个睡眠调用通常会阻塞远超过一毫秒(它取决于操作系统和系统,但根据我的经验, Thread.Sleep(1)往往会阻塞12-15ms之间的某个位置)。

通常,Windows不是作为实时操作系统设计的 。 在普通(桌面/服务器)版本的Windows上通常无法实现此类控制。

您可以获得的最接近的通常是旋转并占用CPU周期,直到您达到所需的等待时间(使用高性能计数器测量)。 然而,这非常糟糕 – 你会占用整个CPU,即使这样,你很可能会被操作系统抢占 ,有效地“睡眠”时间超过1毫秒……

下面的代码绝对会提供更精确的阻塞方式,而不是调用Thread.Sleep(x); (虽然这种方法会阻塞线程,但不能让它睡觉 )。 下面我们使用StopWatch类来测量我们需要多长时间来保持循环并阻塞调用线程。

 using System.Diagnostics; private static void NOP(double durationSeconds) { var durationTicks = Math.Round(durationSeconds * Stopwatch.Frequency); var sw = Stopwatch.StartNew(); while (sw.ElapsedTicks < durationTicks) { } } 

用法示例,

 private static void Main() { NOP(5); // Wait 5 seconds. Console.WriteLine("Hello World!"); Console.ReadLine(); } 

为什么?
通常,一台机器上的CPU和核心数量非常有限 – 如果是独立的执行单元,您只能得到一小部分。

另一方面,有许多进程和更multithreading。 每个线程都需要一些处理器时间,这是由Windows核心进程内部分配的。 通常,Windows会阻塞所有线程并为特定线程提供一定量的CPU核心时间,然后将上下文切换到其他线程。

当你调用Thread.Sleep无论你杀掉Windows给线程的整个时间跨度有多小,因为没有理由等待它直接切换上下文。 当Windows下次为您的线程提供一些CPU时,可能需要几毫秒。

用什么?
或者,你可以旋转你的CPU ,旋转不是一件可怕的事情,并且非常有用。 例如,它在System.Collections.Concurrent命名空间中使用很多非阻塞集合,例如:

 SpinWait sw = new SpinWait(); sw.SpinOnce(); 

使用Thread.Sleep(1)Thread.Sleep(0)大多数合理原因涉及相当高级的线程同步技术。 就像里德所说的那样 ,你不会使用传统技术获得所需的分辨率。 我不确定你想要完成什么,但我想我可以假设你想要以1毫秒的间隔发生一次动作。 如果是这种情况,那么请看一下多媒体计时器 。 它们可以提供低至1毫秒的分辨率。 不幸的是,.NET Framework中没有内置的API(我知道)可以利用这个Windowsfunction。 但您可以使用互操作层直接调用Win32 API。 甚至有一些在C#中执行此操作的示例。

在过去的好时光中,当需要亚毫秒分辨率时,您将使用Win32的“QueryPerformanceTimer”API。

关于Code-Project的主题似乎有更多信息: http : //www.codeproject.com/KB/cs/highperformancetimercshar.aspx

这将不允许您使用Reed Copsey指出的相同分辨率“Sleep()”。

编辑:正如Reed Copsey和Brian Gideon所指出的,QueryPerfomanceTimer已被.NET中的Stopwatch取代

根据我的经验,这类似于没有睡觉

 Thread.Sleep(1/3) 

我没有测试睡眠时间的确切时间,但这是我到达此线程时所寻找的答案。 所以,它可能也会帮助其他人。 确切地说,我一直在寻找不到1毫秒的睡眠时间。