Eri*_*bes 13 c# multithreading sleep timeout waithandle
Thread.Sleep(timeout)和resetEvent.Wait(timeout)都会导致执行暂停至少timeout几毫秒,那么它们之间是否存在差异?我知道Thread.Sleep导致线程放弃其时间片的剩余部分,因此可能导致睡眠持续时间远远超过要求的时间.ManualResetEvent对象的Wait(timeout)方法是否具有相同的问题?
编辑:我知道一个ManualResetEvent的主要要点是从另一个线程发出信号 - 现在我只关注事件的Wait方法的情况,指定了超时,没有其他调用者设置事件.我想知道是否比Thread.Sleep更准确地唤醒准时
Thread.Sleep和之间的主要区别在于ManualResetEvent.WaitOne,您可以使用Set方法向使用SetResetEvent等待的线程发出信号,从而导致线程在超时之前唤醒.
如果你没有发出信号,那么我希望它们的表现方式非常相似.
从.NET Reflector我可以看到该方法ManualResetEvent.WaitOne最终导致使用以下签名调用extern方法:
int WaitOneNative(SafeWaitHandle waitHandle,
uint millisecondsTimeout,
bool hasThreadAffinity,
bool exitContext);
Run Code Online (Sandbox Code Playgroud)
而Thread.Sleep调用这种外部方法:
void SleepInternal(int millisecondsTimeout);
Run Code Online (Sandbox Code Playgroud)
不幸的是我没有这些方法的源代码,所以我只能猜测.我想,在两次调用中都会导致线程在等待超时时间之前被调度出来,而且两者都没有特别准确.
对于延迟和周期,我发现Monitor.Wait是个不错的选择..
object timelock = new object();
lock (timelock) { Monitor.Wait(timelock, TimeSpan.FromMilliseconds(X.XX)); }
Run Code Online (Sandbox Code Playgroud)
这样可以获得出色的结果......〜1ms抖动或更好,具体取决于具体应用.
你可能已经知道Thread.Sleep(X)是不可靠的,不能取消....我像瘟疫一样避免它.
Sleep() 函数已经很长时间没有以这种方式工作了。它的准确性由多媒体计时器周期决定,您可以通过 P/Invoking timeBeginPeriod() 更改该周期。不幸的是,在我的机器上,我有某种程序可以将此周期设置为一毫秒,从而使睡眠精确到一毫秒。这里有一些代码供您自己尝试:
using System;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
//timeBeginPeriod(1);
var sw1 = Stopwatch.StartNew();
for (int ix = 0; ix < 100; ++ix) Thread.Sleep(10);
sw1.Stop();
var sw2 = Stopwatch.StartNew();
var mre = new ManualResetEvent(false);
for (int ix = 0; ix < 100; ++ix) mre.WaitOne(10);
sw1.Stop();
Console.WriteLine("Sleep: {0}, Wait: {1}", sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds);
Console.ReadLine();
//timeEndPeriod(1);
}
[DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int period);
[DllImport("winmm.dll")]
private static extern int timeEndPeriod(int period);
}
Run Code Online (Sandbox Code Playgroud)
我的机器上的输出:
睡眠:999,等待:1003
变化约为 5 毫秒。