螺纹。睡得不到1毫秒
我想以不到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);
}
我很高兴能对此获得意见。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
下面的代码绝对会提供更精确的阻塞方式,而不是调用
thread.sleep(x);
(尽管此方法将 block the线程,而不是放置它到睡眠)。在下面,我们使用stopwatch
类来测量需要保持循环并阻止调用线程的时间。示例用法,
The code below will most definitely offer a more precise way of blocking, rather than calling
Thread.Sleep(x);
(although this method will block the thread, not put it to sleep). Below we are using theStopWatch
class to measure how long we need to keep looping and block the calling thread.Example usage,
为什么?
通常,一台机器上的CPU和内核数量非常有限 - 如果独立执行单元,您只会得到一个少量。
从另一只手中,有许多过程和更多线程。每个线程都需要一些处理器时间,这是由Windows Core进程内部分配的。通常,Windows会阻止所有线程,并为特定线程提供一定数量的CPU核心时间,然后将上下文切换到其他线程。
当您调用线程时,无论您杀死窗口的整个时间范围有多小,都没有理由简单地等待它,并且上下文立即切换。下次Windows给您的线程一些CPU时,可能需要几个MS。
使用什么?
另外,您可以旋转您的CPU ,旋转不是一件可怕的事情要做,而且非常有用。例如,它在 system.collections.concurrent 中使用了很多非阻止集合的命名空间,例如:
Why?
Usually there are a very limited number of CPUs and cores on one machine - you get just a small number if independent execution units.
From the other hands there are a number of processes and many more threads. Each thread requires some processor time, that is assigned internally by Windows core processes. Usually Windows blocks all threads and gives a certain amount of CPU core time to particular threads, then it switches the context to other threads.
When you call Thread.Sleep no matter how small you kill the whole time span Windows gave to the thread, as there is no reason to simply wait for it and the context is switched straight away. It can take a few ms when Windows gives your thread some CPU next time.
What to use?
Alternatively, you can spin your CPU, spinning is not a terrible thing to do and can be very useful. It is for example used in System.Collections.Concurrent namespace a lot with non-blocking collections, e.g.:
使用
thread.sleep(1)
或thread.sleep(0)
的大多数合法原因涉及相当高级的线程同步技术。喜欢。他们可以将分辨率降至1毫秒。不幸的是,在.NET框架(我知道)中没有内置的API,可以攻入此Windows功能。但是您可以使用Interop层直接呼叫到Win32 API。甚至还有在C#中这样做的例子。Most of the legitimate reasons for using
Thread.Sleep(1)
orThread.Sleep(0)
involve fairly advanced thread synchronization techniques. Like Reed said, you will not get the desired resolution using conventional techniques. I do not know for sure what it is you are trying to accomplish, but I think I can assume that you want to cause an action to occur at 1 millisecond intervals. If that is the case then take a look at multimedia timers. They can provide resolution down to 1ms. Unfortunately, there is no API built into the .NET Framework (that I am aware of) that taps into this Windows feature. But you can use the interop layer to call directly into the Win32 APIs. There are even examples of doing this in C# out there.在过去的美好时光中,您将使用Win32的“ QueryPerformanceTimer” API,当时需要进行下milisecond分辨率。
在Code-project上,似乎有更多有关该主题的信息: http:http://www。 codeproject.com/kb/cs/highperformancetimercshar.aspx
这不允许您以与Reed Copsey指出的分辨率相同的分辨率“ Sleep()”。
编辑:
正如里德·科普西(Reed Copsey)和布莱恩·吉迪恩(Brian Gideon
In the good old days, you would use the "QueryPerformanceTimer" API of Win32, when sub milisecond resolution was needed.
There seems to be more info on the subject over on Code-Project: http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx
This won't allow you to "Sleep()" with the same resolution as pointed out by Reed Copsey.
Edit:
As pointed out by Reed Copsey and Brian Gideon the QueryPerfomanceTimer has been replaced by
Stopwatch
in .NET我一直在寻找与OP相同的东西,并设法找到了对我有用的答案。我很惊讶其他答案都没有提到这一点。
当您调用thread.sleep()时,您可以使用两个过载之一:一个毫秒数,或timespan 。
Timespan的构造函数又有许多过载。 其中之一是一个长长的长度,表示时间pan代表的tick虫数量。一个tick小于1毫秒。实际上,时代文档的另一部分举例说明了1毫秒内发生10000个滴答声。
因此,我认为问题最接近的答案是,如果您想要螺纹。小于1ms的睡眠,您将创建一个timespan,timespan的价值少于1毫秒,然后将其传递给thread.sleep()。
I was looking for the same thing as the OP, and managed to find an answer that works for me. I'm surprised that none of the other answers mentioned this.
When you call Thread.Sleep(), you can use one of two overloads: An int with the number of milliseconds, or a TimeSpan.
A TimeSpan's Constructor, in turn, has a number of overloads. One of them is a single long denoting the number of ticks the TimeSpan represents. One tick is a lot less than 1ms. In fact, another part of TimeSpan's docs gave an example of 10000 ticks happening in 1ms.
Therefore, I think the closest answer to the question is that if you want Thread.Sleep for less than 1ms, you would create a TimeSpan with less than 1ms worth of ticks, then pass that to Thread.Sleep().
你不能这样做。一个单个睡眠调用通常会比一个毫秒(依赖OS和系统依赖)阻塞更长的时间,但是根据我的经验,
thread.sleep.sleep(1)
倾向于阻止12-15ms之间的某个位置)。通常,Windows并未被设计为实时操作系统。通常,这种类型的控件在正常的(桌面/服务器)版本的Windows上是不可能实现的。
您可以获得的最接近通常是旋转和吃CPU周期,直到达到想要的等待时间为止(使用高性能计数器测量)。但是,这非常糟糕 - 您会吃掉整个CPU,即使那样,您也可能会得到有时被OS抢占,有效地“睡眠”超过1ms ...
You can't do this. A single sleep call will typically block for far longer than a millisecond (it's OS and system dependent, but in my experience,
Thread.Sleep(1)
tends to block for somewhere between 12-15ms).Windows, in general, is not designed as a real-time operating system. This type of control is typically impossible to achieve on normal (desktop/server) versions of Windows.
The closest you can get is typically to spin and eat CPU cycles until you've achieved the wait time you want (measured with a high performance counter). This, however, is pretty awful - you'll eat up an entire CPU, and even then, you'll likely get preempted by the OS at times and effectively "sleep" for longer than 1ms...