1

時間を表示するいくつかの異なるアプリケーションを作成しました。アプリケーションが実行されているマシンは Windows 7 上にあり、インターネットにアクセスできません。

現在の実装は、各アプリケーションのタイマーで、間隔は 1000 ミリ秒で、グラブDateTime.Nowして表示します。残念ながら、これはアプリケーションが互いに視覚的に同期していないことも意味します。最悪のシナリオでは、アプリケーションが他のアプリケーションよりも 999 ミリ秒遅い時間を表示します。「ラグ/トレーリング」は、すべて 1 秒以内ですが、かなり目立ちます。

タイマーを 100 ミリ秒間隔に変更できますが、長期的には CPU リソースにどのような影響があるかわかりません。システムクロックが更新されるたびにトリガーされる「Windows Interupt」を使用できるとも言われましたが、それに関する情報が見つからないようです。誰かが私を正しい方向に向けることができますか?

アプリ内の時間が完全に同期している必要はありません (ミリ秒単位)。

4

3 に答える 3

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 スレッドをブロックするため、別のスレッドで実行することをお勧めします。

于 2013-07-02T06:36:15.363 に答える
0

Windows タイム サービスを使用することは解決策ではありませんか? なぜ車輪を再発明するのですか?

「Windows タイム サービスはネットワーク タイム プロトコル (NTP) の正確な実装ではありませんが、NTP 仕様で定義されている一連の複雑なアルゴリズムを使用して、ネットワーク全体のコンピューターのクロックが可能な限り正確であることを保証します。理想的には、 、AD DS ドメイン内のすべてのコンピューターの時計は、権限のあるコンピューターの時刻と同期されています。多くの要因がネットワーク上の時刻の同期に影響を与える可能性があります。」

http://technet.microsoft.com/en-us/library/cc773013(v=ws.10).aspx

于 2013-07-02T06:36:13.750 に答える
-1
using System.Net;
using System.Net.Sockets;

名前空間クロック { public 部分クラス Form1 : Form { public 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;
    }
}

}

于 2016-05-02T14:53:31.720 に答える