2010-12-07 88 views
0

我正在做一個應用程序,需要某種類型的系統時鐘,計數滴答的時鐘。我應該能夠獲得計數值並進行設置。在C#中使用計時器線程

我已經使用Python語言中的線程庫完成了它,但我無法對C#中的Timer類做同樣的事情。作爲.NET新手,我不確定這個計時器類是如何工作的。我很想能夠使用.NET實現相同的時鐘。

這是我的Python代碼,所以你可以瞭解我在說什麼。

class SystemClock(threading.Thread): 

    def __init__(self , timeUnit , sched): 
     self.val = 0 

     self.unit = timeUnit 
     self.stp= False 
     self.sched = sched 
     threading.Thread.__init__(self) 

    def run(self): 
     while not self.stp: 
      self.val +=1 
      time.sleep(self.unit) 

    def getSystemTime(self): 
     return self.val 

    def stop(self): 
     self.stp = True 

我感謝您的幫助;

+1

你的Python代碼使*非常*窮計時器,它很快落後。至少使用Environment.TickCount或DateTime.Now,它不需要線程。 – 2010-12-07 23:57:58

回答

1

是否有任何理由不開始在開始時檢索DateTime,並根據需要使用DateTime.Now.Subtract(origDateTime)並根據需要使用TimeSpan結果?或者這是每次打勾更新的東西?

編輯 此外,與定時器一樣,您設置了「滴答」間隔,因此您不需要睡眠它們。每個勾號將執行回調,節省您使用一段時間...睡眠的麻煩。但是在線程中,儘管在線程領域,我無法驗證,因爲我已經使用了定時器已經有一段時間了,您可能需要將正在修改的變量鎖定爲(),因爲它在單獨的線程中,因爲沒有任何東西確保另一種方法不會改變相同的價值。

EDITv3

下面是編輯的版本3。你有兩個類,都避免使用定時器(你的CPU稍後會感謝我; -p)SystemClock是一個典型的每秒一次的間隔速率。 VariableSystemClock允許您指定增加的比率。我也改變了從屬性值到方法的方式,甚至使用了繼承。 ;-)

SystemClock.cs

public class SystemClock 
{ 
    protected DateTime _start; 

    public SystemClock() 
    { 
     this._start = DateTime.UtcNow; 
    } 

    public virtual Int32 getSystemTime() 
    { 
     return Convert.ToInt32(Math.Floor(DateTime.UtcNow.Subtract(this._start).TotalSeconds)); 
    } 
} 

VariableSystemClock.cs

public class VariableSystemClock : SystemClock 
{ 
    private TimeSpan _interval; 

    public VariableSystemClock(TimeSpan interval) 
     : base() 
    { 
     this._interval = interval; 
    } 

    public override Int32 getSystemTime() 
    { 
     Double ellapsed = DateTime.UtcNow.Subtract(this._start).Ticks/this._interval.Ticks; 
     return Convert.ToInt32(Math.Floor(ellapsed)); 
    } 
} 

Program.cs的(因此可以在一個控制檯應用程序對其進行測試(項目 - >新建 - >控制檯應用程序)

class Program 
{ 
    static void Main(string[] args) 
    { 
     SystemClock oncePerSecond = new SystemClock(); 
     VariableSystemClock oncePerInterval = new VariableSystemClock(TimeSpan.FromSeconds(2)); 

     Console.WriteLine("Start:"); 
     Console.WriteLine(" oncePerSecond: {0}", oncePerSecond.getSystemTime()); 
     Console.WriteLine(" oncePerInterval: {0}", oncePerInterval.getSystemTime()); 
     Console.WriteLine(); 

     for (Int32 i = 0; i < 10; i++) 
     { 
      // sleep three seconds 
      System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2)); 

      // display output 
      Console.WriteLine("Interval {0}:", i); 
      Console.WriteLine(" oncePerSecond: {0}", oncePerSecond.getSystemTime()); 
      Console.WriteLine(" oncePerInterval: {0}", oncePerInterval.getSystemTime()); 
      Console.WriteLine(); 
     } 

     Console.WriteLine("End:"); 
     Console.WriteLine(" oncePerSecond: {0}", oncePerSecond.getSystemTime()); 
     Console.WriteLine(" oncePerInterval: {0}", oncePerInterval.getSystemTime()); 
     Console.WriteLine(); 
    } 
} 

隨意使用oncePerInterval構造和for循環中的Sleep。

+0

沒有道理,如果有另一種方式,我會很高興,如果你告訴我 – Nataly 2010-12-07 23:55:46

3

爲什麼不只是使用System.Diagnostics.Stopwatch,因爲這是正好是它是什麼。

// at the start of your program 
Stopwatch SystemClock = Stopwatch.StartNew(); 

// any time you want to see how much time has elapsed 
long ticks = SystemClock.ElapsedTicks; 

如果你真正需要的是能夠設置的值,然後在具有base_time值(蜱)一類包裝一下,然後加入經過蜱你的基地的時間才能拿到一次想。