2013年11月29日 星期五

C# Timer

C# Timer可以提供定期執行特定行為的實作。
而Timer本身的事件即是觸發新的Thread去執行該行為。
MSDN上的範例相當完整,
大家可去實作看看。
這邊提供幾個特定的範例供參考。


範例一:基本Timer

int Count = 0;
 Timer _timer = new Timer();
public void useTimer(  )
{
 _timer.Interval = 1000;//設定Timer的觸發時間
 _timer.Elapsed += _CoumterAndWrite;//指定被觸發的事件。
 _timer.Start();//啟動Timer
}
//被觸發的事件
internal void _CoumterAndWrite( object sender, ElapsedEventArgs e )
{
 for ( int i = 0; i < 10; i++ )
 {
  int id = Thread.CurrentThread.ManagedThreadId;
  int val = Count;
  Console.WriteLine( id + "---Count : " + val );
  Thread.Sleep( 100 );
  Count++;
  Thread.Sleep( 500 );
  if ( Count > 100 )
  {
   _timer.Stop();
  }
 }
}

Result:









從執行結果可以發現,他會互搶。
就是因為觸發了多執行緒,
而且沒有lock機制,
所以實作上要小心。

範例二:更改AutoReset為false 使Timer只會執行一次。

int Count = 0;
 Timer _timer = new Timer();
public void useTimer(  )
{
 _timer.Interval = 1000;//設定Timer的觸發時間
 _timer.Elapsed += _CoumterAndWrite;//指定被觸發的事件。
 _timer.Start();//啟動Timer
 _timer.AutoReset = !_timer.AutoReset;//一定要Start後更改才有效。
 Console.WriteLine( "目前AutoReset =" + _timer.AutoReset );
}
//被觸發的事件
internal void _CoumterAndWrite( object sender, ElapsedEventArgs e )
{
 for ( int i = 0; i < 10; i++ )
 {
  int id = Thread.CurrentThread.ManagedThreadId;
  int val = Count;
  Console.WriteLine( id + "---Count : " + val );
  Thread.Sleep( 100 );
  Count++;
  Thread.Sleep( 500 );
  if ( Count > 100 )
  {
   _timer.Stop();
  }
 }
}

Result










如果沒有在Timer Start後才更改AutoReset,
這樣AutoReset會無效。

範例三:利用Enabled達成若上次觸發的事件還沒做完,則觸發無效。
int Count = 0;
 Timer _timer = new Timer();
public void useTimer(  )
{
 _timer.Interval = 1000;//設定Timer的觸發時間
 _timer.Elapsed += _CoumterAndWrite;//指定被觸發的事件。
 _timer.Start();//啟動Timer
 _timer.AutoReset = !_timer.AutoReset;//一定要Start後更改才有效。
 Console.WriteLine( "目前AutoReset =" + _timer.AutoReset );
}
//被觸發的事件
internal void _CoumterAndWriteByEnabled( object sender, ElapsedEventArgs e )
{
 _timer.Enabled = false;
 Console.WriteLine( "目前Enabled =" + _timer.Enabled );
 for ( int i = 0; i < 10; i++ )
 {
  int id = Thread.CurrentThread.ManagedThreadId;
  int val = Count;
  Console.WriteLine( id + "---Count : " + val );
  Thread.Sleep( 100 );
  Count++;
  Thread.Sleep( 500 );
  if ( Count > 100 )
  {
   _timer.Stop();
  }
 }
 _timer.Enabled = true;
 Console.WriteLine( "目前Enabled =" + _timer.Enabled );
}

Result
















這樣就可以確保不會互搶了~
不過就會失去部分Timer的意義~
例子很極端~僅供參考。