2013-11-01 18 views
6

Tôi đang cố gắng triển khai dịch vụ thời gian sẽ báo cáo thời gian có độ chính xác cao hơn 1ms. Tôi nghĩ rằng một giải pháp dễ dàng sẽ là để có một đo lường ban đầu và sử dụng StopWatch để thêm một đồng bằng với nó. Vấn đề là phương pháp này dường như phân kỳ cực nhanh từ thời gian tường. Ví dụ, đoạn mã sau cố gắng để đo sự phân kỳ giữa tường Thời gian và Nghị quyết Clock cao của tôi:Cách tốt nhất để triển khai DateTime.UtcNow có độ phân giải cao trong C#?

public static void Main(string[] args) 
{ 
    System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch(); 
    DateTime baseDateTime = DateTime.UtcNow; 
    s.Start(); 
    long counter = 0; 
    while(true) 
    { 
     DateTime utcnow = DateTime.UtcNow; 
     DateTime hpcutcnow = baseDateTime + s.Elapsed; 
     Console.WriteLine(String.Format("{0}) DT:{1} HP:{2} DIFF:{3}", 
      ++counter, utcnow, hpcutcnow, utcnow - hpcutcnow)); 
     Thread.Sleep(1000); 
    } 
} 

Tôi đang phân kỳ với tốc độ khoảng 2ms/phút trên phần cứng sever khá gần đây.

Có cơ sở thời gian nào khác trong cửa sổ mà tôi không biết điều đó sẽ chính xác hơn không? Nếu không, có cách nào tốt hơn để tạo đồng hồ có độ phân giải cao hoặc thư viện của bên thứ ba mà tôi nên sử dụng không?

+2

Câu hỏi: Nếu 'DateTime.UtcNow' không đủ chính xác cho bạn, bạn sẽ sử dụng dịch vụ thời gian nào để sử dụng dịch vụ thời gian của mình? – StriplingWarrior

+0

Ngoài câu trả lời tuyệt vời của @ Hans tôi sẽ thêm rằng bạn có thể cố gắng thực hiện điều này bằng thiết bị phần cứng (một thứ có "bộ dao động tinh thể đắt tiền"). Tôi không chắc chắn nếu bạn có thể chuyển [và sử dụng] thời gian phụ ms trên một hộp Windows. –

Trả lời

8

Bắt đồng hồ chính xác rất khó. Đồng hồ bấm giờ có độ phân giải rất cao, nhưng nó không chính xác, phát sinh tần số của nó từ tín hiệu trong chipset. Mà hoạt động ở dung sai phần điện tử điển hình. Sự cạnh tranh khốc liệt trong việc kinh doanh phần cứng đã ngăn chặn các bộ dao động tinh thể đắt tiền với tần số được đảm bảo và ổn định.

DateTime.UtcNow cũng không chính xác, nhưng nó được trợ giúp. Windows định kỳ liên lạc với dịch vụ thời gian, mặc định là dịch vụ time.windows.com để có được bản cập nhật của đồng hồ chất lượng cao. Và sử dụng nó để hiệu chỉnh lại đồng hồ của máy, chèn các điều chỉnh nhỏ để đồng hồ bắt kịp hoặc giảm tốc độ.

Bạn cần nhiều thủ thuật lớn hơn để giảm độ chính xác xuống một phần nghìn giây. Bạn chỉ có thể nhận được sự bảo đảm giống như mã chạy trong chế độ hạt nhân, chạy ở mức độ ưu tiên ngắt vì vậy nó không thể bị chèn trước bởi mã khác và mã và trang dữ liệu của nó được khóa trang để nó không bị ảnh hưởng bởi lỗi trang . Giải pháp thương mại sử dụng một đài phát thanh GPS để đọc tín hiệu đồng hồ của các vệ tinh GPS, được sao lưu bởi một bộ dao động chạy trong lò để cung cấp ổn định nhiệt độ. Việc đọc đồng hồ như vậy là vấn đề khó, bạn không có nhiều sử dụng cho nguồn đồng hồ phần nghìn giây khi chương trình của bạn sử dụng nó có thể bị hệ điều hành làm trống trước khi nó thu được thời gian và không bắt đầu chạy lại cho đến khi ~ 45 ms sau. Hoặc tồi tệ hơn.

DateTime.UtcNow chính xác đến 15.625 mili giây và ổn định trong khoảng thời gian rất dài nhờ vào bản cập nhật dịch vụ thời gian. Đi thấp hơn điều đó không có ý nghĩa nhiều, bạn không thể có được sự đảm bảo thực hiện mà bạn cần trong chế độ người dùng để tận dụng nó.

4

Dường như trong Windows 8/Server 2012, API mới được thêm cụ thể để nhận được dấu thời gian có độ phân giải cao, API GetSystemTimePreciseAsFileTime. Tôi đã không có cơ hội để chơi với điều này, nhưng có vẻ đầy hứa hẹn.

Các vấn đề liên quan