Thread.Sleep小于1毫秒

时间:2011-06-06 15:57:21

标签: c# .net multithreading

我想用不到1毫秒的时间调用线程休眠。 我读到没有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);
 }

我很高兴得到你的意见。

7 个答案:

答案 0 :(得分:41)

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

Windows通常不是设计为real-time operating system。在普通(桌面/服务器)版本的Windows上通常无法实现这种类型的控制。

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

答案 1 :(得分:18)

下面的代码肯定会提供一种更精确的阻止方式,而不是调用Thread.Sleep(x);(虽然这种方法会阻塞线程,而不是把它放到 sleep < / em>的)。下面我们使用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();
}

答案 2 :(得分:10)

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

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

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

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

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

答案 3 :(得分:6)

使用Thread.Sleep(1)Thread.Sleep(0)的大多数合法原因都涉及相当高级的线程同步技术。与Reed said一样,使用传统技术无法获得所需的分辨率。我不确定你想要完成什么,但我想我可以假设你想要以1毫秒的间隔发生一次动作。如果是这种情况,请查看multimedia timers。它们可以提供低至1毫秒的分辨率。不幸的是,.NET Framework中没有内置的API(我知道)可以使用这个Windows功能。但是您可以使用互操作层直接调用Win32 API。甚至在C#中也有这样做的例子。

答案 4 :(得分:4)

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

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

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

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

答案 5 :(得分:-2)

关于里德·科普西(Reed Copsey)接受的答案,这怎么样?

getObject(data,'name','Car');

答案 6 :(得分:-4)

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

Thread.Sleep(1/3) 

我没有测试睡眠所需的确切时间(毫秒),但这是我到达此线程时正在寻找的答案。因此,它也可能会帮助其他人。确切地说,我正在寻找少于1毫秒的睡眠时间。