SORU
19 EYLÜL 2010, Pazar


Neden .NET zamanlayıcılar 15 ms çözünürlük sınırlı?

Geri arama fonksiyonu daha sık bir kez her 15 ms daha diyecek bir şey hakkında System.Threading.Timer gibi bir şey kullanmak istiyorum unutmayın. Doğru kodu bir parça zaman hakkında System.Diagnostics.Stopwatch hatta QueryPerformanceCounter gibi bir şey kullanmak istemiyorum.

Ayrıca, ilgili soruları okudum:

http://stackoverflow.com/questions/448761/accurate-windows-timer-system-timers-timer-is-limited-to-15-msec

http://stackoverflow.com/questions/163022/high-resolution-timer-in-net

Ne soruma cevap yararlı bir malzeme.

Buna ek olarak, tavsiye TechNet makale, Implement a Continuously Updating, High-Resolution Time Provider for Windows tikler, sürekli bir akış sağlamak yerine işleri zamanlama ile ilgili.

O dedi. . .

Hakkında dışarıda kötü bir sürü bilgi var .NET zamanlayıcı nesneleri. Örneğin, "yüksek performanslı sunucu uygulamaları için optimize edilmiş zamanlayıcı." diyorlar için Ve System.Threading.Timer nedense ikinci sınıf vatandaş olarak kabul edilir. Geleneksel bilgelik System.Threading.Timer Windows Timer Queue Timers etrafında bir sarıcı olduğunu ve System.Timers.Timer tamamen başka bir şeydir.

Gerçeklik çok farklı. System.Timers.Timer sadece ince bir bileşen etrafında sarıcı System.Threading.Timer (sadece Reflektör ya da ILDASM için içeriye System.Timers.Timer göreceksiniz başvuru System.Threading.Timer), ve bazı kod sağlayacak otomatik bir iş parçacığı eşitleme zorunda kalmamak için.

Meğer System.Threading.Timer,değilZamanlayıcı Kuyruk için bir sarıcı Zamanlayıcılar. Dan kullanılan en az 2.0 çalışma zamanı değil .NET 2.0 .NET 3.5. Paylaşılan Kaynak ile birkaç dakika çalışma zamanı, Zamanlayıcı Sıra Zamanlayıcılar benzer kendi zamanlayıcı sıra uygulayan CLİ gösterir, ama aslında hiç çağrıları win 32 işlevleri.

Bu gibi görünüyor .NET 4.0 çalışma zamanı da kendi zamanlayıcı sırası uygular. Benim test programı (aşağıya bakınız) benzer sonuçlar altında sağlar .Altında olduğu gibi NET 4.0 .NET 3.5. Ben zaten oluşturulan kendim yönetilen sarıcı için Zamanlayıcı Sıra Zamanlayıcılar ve kanıtlayan alabilirim 1 ms çözünürlük (oldukça iyi doğruluk), yani düşünün kuvvetle muhtemel ki ben okuma CLİ kaynak yanlış.

İki sorum var:

İlk olarak, zamanlayıcı sıra çalışma zamanı uygulaması bu kadar yavaş olma nedenleri nelerdir? 15 ms çözünürlük daha iyi bulamıyorum, ve doğruluk 30 ms -1 aralığında gibi görünüyor. Bu, eğer 24 ms istersem, keneler 23 54 ms dışında bir yere varamam. CLİ kaynağı ile biraz daha zaman cevap bulmaya geçirebilirim sanırım. ama birinin burada olduğunu düşündüm.

Bu cevaplaması zor olduğunun farkındayım ikinci, ve, neden kronometre Sıra Zamanlayıcılar kullanmak değil mi? Bunun farkındayım .NET 1.x bu API yoktu Win9x, üzerinde çalıştırmak vardı, ama bu yana, Windows, eğer hatırlıyorsam doğru en az ihtiyacı olan 2000, var .NET 2.0. SİSTEMİNDE non-Windows kutuları üzerinde çalışmak zorunda olduğu için mi?

Zamanlayıcılar benim test programı:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;

namespace TimerTest
{
    class Program
    {
        const int TickFrequency = 5;
        const int TestDuration = 15000;   // 15 seconds

        static void Main(string[] args)
        {
            // Create a list to hold the tick times
            // The list is pre-allocated to prevent list resizing
            // from slowing down the test.
            List<double> tickTimes = new List<double>(2 * TestDuration / TickFrequency);

            // Start a stopwatch so we can keep track of how long this takes.
            Stopwatch Elapsed = Stopwatch.StartNew();

            // Create a timer that saves the elapsed time at each tick
            Timer ticker = new Timer((s) =>
                {
                    tickTimes.Add(Elapsed.ElapsedMilliseconds);
                }, null, 0, TickFrequency);

            // Wait for the test to complete
            Thread.Sleep(TestDuration);

            // Destroy the timer and stop the stopwatch
            ticker.Dispose();
            Elapsed.Stop();

            // Now let's analyze the results
            Console.WriteLine("{0:N0} ticks in {1:N0} milliseconds", tickTimes.Count, Elapsed.ElapsedMilliseconds);
            Console.WriteLine("Average tick frequency = {0:N2} ms", (double)Elapsed.ElapsedMilliseconds / tickTimes.Count);

            // Compute min and max deviation from requested frequency
            double minDiff = double.MaxValue;
            double maxDiff = double.MinValue;
            for (int i = 1; i < tickTimes.Count;   i)
            {
                double diff = (tickTimes[i] - tickTimes[i - 1]) - TickFrequency;
                minDiff = Math.Min(diff, minDiff);
                maxDiff = Math.Max(diff, maxDiff);
            }

            Console.WriteLine("min diff = {0:N4} ms", minDiff);
            Console.WriteLine("max diff = {0:N4} ms", maxDiff);

            Console.WriteLine("Test complete.  Press Enter.");
            Console.ReadLine();
        }
    }
}

CEVAP
19 EYLÜL 2010, Pazar


Belki de belgeyi buraya bağlı biraz açıklıyor. Ben sadece hızlı bir şekilde göz çok kuru:) bir şey

İntro alıntı:

Sistem zamanlayıcı çözünürlüğünü belirler ne sıklıkta Windows iki gerçekleştirir ana eylemler:

  • Update timer tick eğer tam bir kene geçti sayılır.
  • Zamanlanmış bir timer nesnesi olup olmadığını kontrol edin süresi doldu.

Timer tick geçen bir kavramdır izlemek için Windows kullandığı zaman gün ve iplik zaman kuantum kere. Varsayılan olarak, saat kesme ve timer tick aynı, ama Windows veya bir uygulama saatini değiştirebilir kesme süresi.

Varsayılan zamanlayıcı Windows 7 çözünürlük 15,6 milisaniye (ms). Bazı uygulamalar bu azaltır 1 ms, bu azaltmak pil mobil sistemler tarafından üzerinde çalıştırma 25 kadar yüzde.

Aslen: Timers, Timer Resolution, and Development of Efficient Code (docx).

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • aki6336

    aki6336

    14 AĞUSTOS 2008
  • Flash CS6 Video Tutorials for Beginners (Actionscript 3 Gaming)

    Flash CS6 Vi

    14 EYLÜL 2012
  • tsweeney79

    tsweeney79

    21 Ocak 2008