【发布时间】:2011-07-15 09:36:23
【问题描述】:
我有 2 台计算机,它们的时间通过 NTP 同步,确保时间仅相差几毫秒。其中一台计算机将通过 TCP 向另一台计算机发送消息,以在未来指定时间在两台计算机上启动某个 c# 函数。
我的问题是:如何在某个时间以毫秒精度(或更好)触发 C# 中的函数?我需要在程序代码中执行此操作(因此任务计划程序或其他外部程序无济于事)。我猜总是在单独的线程中循环以比较当前时间和目标时间不是一个好的解决方案。
更新:
DateTime.Now 分辨率低,因此无法在解决方案中使用。
似乎可以通过导入强制 Thread.Sleep() 具有 1 毫秒的分辨率:
[DllImport("winmm.dll", EntryPoint="timeBeginPeriod")]
public static extern uint MM_BeginPeriod(uint uMilliseconds);
并使用:
MM_BeginPeriod(1);
要恢复到以前的分辨率导入:
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod")]
public static extern uint MM_EndPeriod(uint uMilliseconds);
并使用:
MM_EndPeriod(1);
更新 2:
我用许多值测试了 Thread.Sleep(),似乎平均而言它会趋向于指定的时间跨度。
仅调用 Thread.Sleep() 一次通常会在目标值时间跨度周围保持半毫秒左右,因此对于毫秒分辨率而言非常精确。
使用 winmm.dll 方法 timeBeginPeriod 和 timeEndPeriod 似乎对结果的准确性没有影响。
解决方案:
一种方法是使用 timeSetEvent(deprecated) 或 CreateTimerQueueTimer。
当前的问题是,两者都需要函数触发的剩余时间而不是它应该触发的时间作为参数。 因此,必须计算触发所需时间的延迟,但 DateTime.Now 提供的分辨率较低。我找到了一个允许高分辨率获取当前日期时间的类。 所以现在剩下的时间可以用高分辨率计算出来,并作为参数传递给 CreateTimerQueueTimer。
【问题讨论】:
-
您需要附加到多媒体领域中的一些实时调度程序。标准线程切换频率约为每 40 毫秒,因此大多数基本的 Thread.Sleep 代码将无法工作。
-
感谢您的回复。我需要一些时间来测试答案。