SORU
12 EYLÜL 2009, CUMARTESİ


Nasıl kene hassas zaman damgası almak için .NET / C#?

Şu ana kadar zaman damgaları almak için DateTime.Now kullandım, ama eğer bir döngü içinde DateTime.Now yazdırmak için bunu yaklaşık küçük atlar, artıran göreceksiniz fark ettim. 15 ms. Ama benim uygulamada bazı senaryolar için (=100 ns) hassas kene ile en doğru zaman damgası mümkün, tercihen lazım. Herhangi bir fikir?

Güncelleme:

AnlaşılanStopWatch / QueryPerformanceCounter yol gitmek, ama sadece kullanılan ölçü zaman, düşünmeye başladım hakkında arama DateTime.Now ne zaman uygulama başlar ve sonra sadece StopWatch çalıştırın ve sonra Ekle geçen zaman StopWatch başlangıç değeri döndü DateTime.Now. En azından bana doğru göreli zaman, değil mi vermeli? O (hack) hakkında ne düşünüyorsunuz?

NOT:

StopWatch.ElapsedTicks StopWatch.Elapsed.Ticks farklıdır! Eski 1 tick = 100 ns, ama bu durumda 1 tick = 1 / StopWatch.Frequencyvarsayarak kullandım. Keneler 14 ** DateTime kullanmak için eşdeğer olsun. Ben bunu zor yoldan öğrendim.

NOT 2:

Kronometre yaklaşım kullanarak, gerçek zaman ile senkronize oluyor fark ettim. Yaklaşık 10 saat sonra, önde 5 saniye oldu. Bir X, 1 saat 30 dakika olabilir, ya da her X~, 15 dakika, vb olurdu sanırım. Resyncing için en uygun zaman aralığı her ~ < 20 ms olan uzaklığı değişir beri ne olacağından emin değilim.

CEVAP
12 EYLÜL 2009, CUMARTESİ


DateTime.Now okuyan sistem saatin değeri sadece o aralıkları etrafında quantized yüzden 15 ms her (veya bazı sistemlerde 10 ms), güncellenir. Orada ek bir örnekleme etkisi olduğu sonucunu verir aslında bu kod çalışan bir çok iş parçacıklı işletim sistemi ve böylece orada uzanıyor nerede uygulaması değil "canlı" ve bu nedenle ölçüm gerçek şimdiki zaman.

Ultra-hassas zaman damgası değeri sadece keyfi bir süre zamanlama (karşıt olarak) aradığın bu yana, kendisi tarafından Stopwatch sınıfı ne istiyorsun. Bunu kendiniz yapmakDateTime/Stopwatch melez bir tür olurdu bence. Uygulama başladığında DateTime.UtcNow geçerli değer (uygulama başladığında ham çözünürlüklü zaman gibi) depolamak ve aynı zamanda Stopwatch bir nesneye başlamak, bu gibi:

DateTime _starttime = DateTime.UtcNow;
Stopwatch _stopwatch = Stopwatch.StartNew();

Yüksek çözünürlüklü DateTime değeri ne zaman ihtiyacın olursa o zaman, bu gibi olacaktı:

DateTime highresDT = _starttime.AddTicks(_stopwatch.Elapsed.Ticks);

Ayrıca de düzenli aralıklarla reset _starttime ve _stopwatch uzak tutmak için ortaya çıkan zaman almak çok uzakta olan sync sistemi zaman (gerçi emin değilim bu gerçekten oldu, ve o-cekti almak a uzun zaman oldu zaten).

Güncelleme: görünüşe göre bu Kronometreyokçık sync sistemi saat (yarım saniyede saat), bence çok mantıklı sıfırlamak hibrit DateTime sınıf tabanlı miktarı zaman ilerledikçe arasındaki aramalar için onay süresi:

public class HiResDateTime
{
    private static DateTime _startTime;
    private static Stopwatch _stopWatch = null;
    private static TimeSpan _maxIdle = 
        TimeSpan.FromSeconds(10);

    public static DateTime UtcNow
    {
        get
        {
            if ((_stopWatch == null) || 
                (_startTime.Add(_maxIdle) < DateTime.UtcNow))
            {
                Reset();
            }
            return _startTime.AddTicks(_stopWatch.Elapsed.Ticks);
        }
    }

    private static void Reset()
    {
        _startTime = DateTime.UtcNow;
        _stopWatch = Stopwatch.StartNew();
    }
}

Eğer reset timer melez bazı düzenli aralıklarla (her saat ya da bir şey), durum biraz riskli ayarı zaman önce son okuma zaman, sanki bir minyatür Yaz Saati sorun.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ASUS

    ASUS

    22 EKİM 2005
  • Boiler Room

    Boiler Room

    10 Mayıs 2012
  • xiaoyu85

    xiaoyu85

    20 ŞUBAT 2010