我想用不到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);
}
我很高兴得到你的意见。
答案 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毫秒的睡眠时间。