我写了几个不同的应用程序,显示时间。运行应用程序的计算机位于Windows 7上,无法访问Internet。
当前实现是每个应用程序中的一个计时器,间隔为1000毫秒,并抓取DateTime.Now
来显示它。不幸的是,这也意味着应用程序在视觉上不会彼此同步,更糟糕的情况是应用程序显示的时间比另一个慢999ms。 “滞后/尾随”非常明显,即使它们都在第二个范围内。
我可以将计时器更改为100毫秒间隔,但我不确定从长远来看它会如何影响CPU资源?我还被告知我可以使用“Windows Interupt”,它会在系统时钟更新时触发,但我似乎无法找到任何信息。有人能指出我正确的方向吗?
我不需要在应用程序中与彼此完全同步(以毫秒为单位)的时间,足以让人眼看到它们在一起滴答。
答案 0 :(得分:1)
您可以使用EventWaitHandle对象构造每个进程可以锁定或阻止的命名事件。每次应用程序更新时间时,您都可以在所有其他应用程序中执行相同的操作。
好的,一些演示代码(未测试):
class TimeSyncTest {
EventWaitHandle _timeSync;
System.Windows.Forms.Timer _refreshTimer;
void DoTimeSync() {
bool wasNew;
_timeSync = new EventWaitHandle(false, EventResetMode.ManualReset, "TimeSync", out wasNew);
if (wasNew) {
_refreshTimer = new System.Windows.Forms.Timer() { Interval = 60000 };
_refreshTimer.Tick += new EventHandler(_refreshTimer_Tick);
_refreshTimer.Start();
} else {
WaitForMasterToTick();
}
}
private void WaitForMasterToTick() {
do {
_timeSync.WaitOne();
RefreshTime();
} while (true);
}
void _refreshTimer_Tick(object sender, EventArgs e) {
_timeSync.Set();
RefreshTime();
_timeSync.Reset();
}
void RefreshTime() {
}
}
当“主”应用程序关闭时,此代码无法处理,其余的将不再更新,您可能还希望运行WaitForMasterToTick
以在单独的线程中运行,因为这将阻止gui线程。
答案 1 :(得分:0)
使用Windows时间服务不是解决方案吗?为什么重新发明轮子?
“虽然Windows时间服务不是网络时间协议(NTP)的精确实现,但它使用NTP规范中定义的复杂算法套件,以确保整个网络中计算机上的时钟与理想情况下,AD DS域中的所有计算机时钟都与权威计算机的时间同步。许多因素都会影响网络上的时间同步。“
http://technet.microsoft.com/en-us/library/cc773013(v=ws.10).aspx
答案 2 :(得分:-1)
using System.Net;
using System.Net.Sockets;
命名空间时钟 { 公共部分类Form1:表格 { 公共Form1() { 的InitializeComponent(); }
private void button1_Click(object sender, EventArgs e)
{
label1.Text = GetNetworkTime().ToString(); //show date and time in label1
}
public static DateTime GetNetworkTime()
{
const string ntpServer = "time.windows.com";
/*
time-a.nist.gov 129.6.15.28 NIST, Gaithersburg, Maryland
time-b.nist.gov 129.6.15.29 NIST, Gaithersburg, Maryland
time-a.timefreq.bldrdoc.gov 132.163.4.101 NIST, Boulder, Colorado
time-b.timefreq.bldrdoc.gov 132.163.4.102 NIST, Boulder, Colorado
time-c.timefreq.bldrdoc.gov 132.163.4.103 NIST, Boulder, Colorado
utcnist.colorado.edu 128.138.140.44 University of Colorado, Boulder
time.nist.gov 192.43.244.18 NCAR, Boulder, Colorado
time-nw.nist.gov 131.107.1.10 Microsoft, Redmond, Washington
nist1.datum.com 209.0.72.7 Datum, San Jose, California
nist1.dc.certifiedtime.com 216.200.93.8 Abovnet, Virginia
nist1.nyc.certifiedtime.com 208.184.49.9 Abovnet, New York City
nist1.sjc.certifiedtime.com 208.185.146.41 Abovnet, San Jose, California
*/
var ntpData = new byte[48];
ntpData[0] = 0x1B; //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)
var addresses = Dns.GetHostEntry(ntpServer).AddressList;
var ipEndPoint = new IPEndPoint(addresses[0], 123);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect(ipEndPoint);
socket.Send(ntpData);
socket.Receive(ntpData);
socket.Close();
ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43];
ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47];
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
DateTime networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);
return networkDateTime;
}
}
}