2010-11-22 8 views
7

私はソフトウェアで時間を測定するためにDateTime.UtcNowを使用しています。「アクションa」が「アクションb」の後10秒以内に発生するかどうかを確認する必要がありますシステム時間が変更されたかどうかを検出するにはどうすればよいですか?

ただし、システム時間は変わりますか?では、システム時間が変更された場合、どのように検出しますか?

、私はまた、仮想マシンが一時停止し、再起動さに対処する必要がhttp://kristofverbiest.blogspot.com/2008/10/beware-of-stopwatch.html

を参照してくださいので、私たちはもっとして一つのCPUを持つサーバー上で実行する必要があるとしてストップウォッチを使用したくない「ダニ数"私にとって有用であるとは思わない。

+0

TimeSpanは時計の変更の影響を受けません。夏時間とタイムゾーンの変更はキャッシュされ、UtcNowには影響しません。 –

答えて

8

SystemEvents.TimeChangedイベントを使用して、変更された時間を検出できます。しかし、これはメッセージポンプが稼働している場合にのみ起動します。これはWindowsクライアントアプリケーションでは問題ありませんが、ほとんどのサーバーアプリケーション(サービス、Webアプリケーションなど)ではそうではありません。

そうでなければEnvironment.TickCountを使用することができます。優れた解像度はありませんが、「10秒」を「ほぼ10秒」にすることができます。 VMの限界までは、マシンが十分に長くなったときにTickCountがロールオーバーするので、おそらくDateTime.UtcNowサニティチェックで処理する必要があります。

私は両方の組み合わせを使用したいと思いますが、とにかくVMケースで動作する正確な既知の外部タイムサーバ(パフォーマンスに影響を与える)をチェックする以外に絶対に正確な方法はありません。問題がある以上の時間を費やす前に、「十分に信頼できる」ものが何であるかを確認してください。

1

あなたは、実行時にシステムクロックの変更を検出するために、SystemEventsクラスのTimeChangedイベントを使用することができます。

http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.timechanged.aspx

これは、メッセージループを持つアプリケーションに依存している(私はWM_TIMECHANGEDメッセージのニーズので、仮定処理されるように)、ヘッドレスアプリケーションの場合は隠しフォームが必要です。 Windowsサービス。

一時停止している仮想マシン上にあるためにアプリケーションが中断されている間に、システムクロックの変化を検出することができます。最後に小切手を実行した時を定期的に記録し、時間が後退していないことを確認するだけです。とにかくVMを中断して再開するのに10秒以上かかることがあります。

4

StopWatchを使用することをお勧めします。 Beware of QueryPerformanceCounterに記載されている問題が依然として存在する場合は、わずか数ミリ秒の違いがあります。負の時間(私が一度も見たことがない何かを心配していて、かなり小さい時間を計るのに多くの時間を使うのはStopWatch)、-1ミリ秒と-1000ミリ秒の間の何かを0として扱います。

任意のタイミングでDateTime.NowまたはDateTime.UtcNowを使用すると、誰かがマシンの日付/時刻を変更すると問題が発生します。あなたは完全にコンピュータの内部にあるものを使う必要があり、変更することはできません。 StopWatchは私が見つけた最も信頼できるものです。

0

私は、2つの時間間隔の間にシステム時間差をモノクロックで比較します。あなたのマシン上で日付と時刻を変更した人よりも差が大きい場合

関連する問題