2012-04-25 58 views
0

在我以前的問題how to suspend a thread for 1 ms?有人回答說,爲了引入1毫秒的延遲我應該使用計時器。哪個定時器用於在迭代之間引入1-5 ms的延遲?

我需要「做功」,然後等待平均2毫秒(1-5毫秒是好的,沒關係很少嚴重延遲達到幾個毫秒),然後再次工作。當前一次迭代尚未完成時,不要試圖開始新的迭代很重要,所以我不需要每1-5毫秒進行一次操作,迭代之間需要1-5毫秒的延遲。

我試圖做到這一點使用System.Timers.Timer,但它不工作:

using System; 
using System.Diagnostics; 
using System.Threading; 
using System.Timers; 
using Timer = System.Timers.Timer; 

namespace TestTimer 
{ 
    class Program 
    { 
     static Timer refresh_timer; 
     private static int called; 
     private const int ITERATIONS = 100; 
     private static Stopwatch sw; 

     static void Main(string[] args) 
     { 
      refresh_timer = new Timer(1); 
      refresh_timer.AutoReset = false; 
      refresh_timer.Elapsed += OnRefreshTimedEvent; 
      sw = Stopwatch.StartNew(); 
      refresh_timer.Start(); 
      Thread.Sleep(10000); 
     } 

     static void OnRefreshTimedEvent(object source, ElapsedEventArgs args) 
     { 
      DoGateIteration(); 
     } 

     private static void DoGateIteration() 
     { 
      //try 
      //{ 
       // work here 
       called++; 
      //} 
      //finally 
      //{ 
       if (called == ITERATIONS) 
       { 
        Console.WriteLine("Average iterations per second: " + ITERATIONS * 1000/sw.ElapsedMilliseconds); 
        Console.WriteLine("Average iterations milliseconds: " + sw.ElapsedMilliseconds/ITERATIONS); 
       } 
       refresh_timer.Start(); 
      //} 
     } 
    } 
} 

據報道:

Average iterations per second: 64 
Average iterations milliseconds: 15 

如此看來System.Timers.Timer是不是準確,因爲我需要。 也許我應該試試System.Threading.Timer,但是這個計時器沒有我需要的AutoReset屬性。

你會建議什麼?

+0

的PInvoke timeBeginPeriod(1),使計時器睡覺精確到毫秒。對功耗不太友好。 – 2012-04-25 11:45:32

回答

0

只有1或2毫秒這樣短的延遲,這可能是最好只是忙等待:

private static int called; 
private const int ITERATIONS = 10000; 
private static Stopwatch sw; 

static void Main(string[] args) 
{ 
    sw = Stopwatch.StartNew(); 

    var x = Stopwatch.StartNew(); 
    while (true) 
    { 
     DoGateIteration(); 

     x.Restart(); 
     while (x.ElapsedMilliseconds < 2) ; // busy-wait for 2 ms 
    } 
} 

private static void DoGateIteration() 
{ 
    called++; 
    if (called == ITERATIONS) 
    { 
     Console.WriteLine("Average iterations per second: " + ITERATIONS * 1000/sw.ElapsedMilliseconds); 
     Console.WriteLine("Average iterations milliseconds: " + sw.ElapsedMilliseconds/ITERATIONS); 
    } 
} 

輸出:

 
Average iterations per second: 500 
Average iterations milliseconds: 2 
+0

這似乎是正確的答案。 'Thread.Sleep(1);'似乎對我來說產生大約10毫秒...... – AKX 2012-04-25 08:00:05

+0

但是這不會釋放處理器能力......我不確定它有多好,因爲我將處於忙等待循環每1秒700毫秒。 – javapowered 2012-04-25 08:22:13