2009-04-14 34 views
6

我在看如何暫停System.Timers.Timer,我無法找出正確的方法來暫停它,而無需重置計時器。正確的方法來暫停System.Timers.Timer?

如何暫停它?

+0

我要回家了,所以回到大約1小時後,看看我收到了什麼回覆。 – Fredou 2009-04-14 19:46:20

+0

sw應該是_sw。 – 2009-04-14 20:43:19

+0

我不知道我是否會在Pause()中更新Interval,我可能會保留私有值。 – 2009-04-14 20:44:34

回答

3

我得到了現在,我敢肯定,這不是防彈所以告訴我什麼是錯的吧...

Public Class ImprovedTimer 
Inherits System.Timers.Timer 

Private _sw As System.Diagnostics.Stopwatch 
Private _paused As Boolean 
Private _originalInterval As Double 
Private _intervalRemaining As Double? 

Public ReadOnly Property IntervalRemaining() As Double? 
    Get 
     Return _intervalRemaining 
    End Get 
End Property 

Public ReadOnly Property Paused() As Boolean 
    Get 
     Return _paused 
    End Get 
End Property 

Public ReadOnly Property OriginalInterval() As Double 
    Get 
     Return _originalInterval 
    End Get 
End Property 

Public Sub Pause() 
    If Me.Enabled Then 
     _intervalRemaining = Me.Interval - _sw.ElapsedMilliseconds 
     _paused = True 
     resetStopWatch(False, False) 
     MyBase.Stop() 
    End If 
End Sub 

Public Sub [Resume]() 
    If _paused Then 
     Me.Interval = If(_intervalRemaining.HasValue, _intervalRemaining.Value, _originalInterval) 
     resetStopWatch(True, False) 
     MyBase.Start() 
    End If 
End Sub 

Public Overloads Property Enabled() As Boolean 
    Get 
     Return MyBase.Enabled 
    End Get 
    Set(ByVal value As Boolean) 
     MyBase.Enabled = value 
     resetStopWatch(MyBase.Enabled, True) 
    End Set 
End Property 

Public Overloads Sub Start() 
    resetStopWatch(True, True) 
    MyBase.Start() 
End Sub 

Public Overloads Sub [Stop]() 
    resetStopWatch(False, True) 
    MyBase.Stop() 
End Sub 

Public Overloads Property Interval() As Double 
    Get 
     Return MyBase.Interval 
    End Get 
    Set(ByVal value As Double) 
     MyBase.Interval = value 
     If Not _paused Then 
      _originalInterval = MyBase.Interval 
     End If 
    End Set 
End Property 

Private Sub resetStopWatch(ByVal startNew As Boolean, ByVal resetPause As Boolean) 
    If _sw IsNot Nothing Then 
     _sw.Stop() 
     _sw = Nothing 
    End If 
    If resetPause Then 
     If _paused Then 
      Me.Interval = _originalInterval 
     End If 
     _paused = False 
     _intervalRemaining = Nothing 
    End If 
    If startNew Then 
     _sw = System.Diagnostics.Stopwatch.StartNew 
    End If 
End Sub 

Private Sub ImprovedTimer_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed 
    resetStopWatch(False, True) 
End Sub 

Private Sub ImprovedTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Me.Elapsed 
    resetStopWatch(Me.AutoReset, True) 
End Sub 

End Class 
6

沒有停頓(),你可以寫一個關於暫停():

  1. 變化(Timeout.Infinite,Timeout.Infinite)
  2. 保存計算計時器的剩餘量。

    1. 變化(剩餘計時器量)

    如果你寫了這個類,請張貼在回答,因爲它似乎我們很多人需要這些功能:

上個人簡歷()

脫離Timer類。 :)

+0

我剛剛做到了,你覺得怎麼樣?在1小時後回來 – Fredou 2009-04-14 19:47:32

0

你應該按照Shay Erlichmen給出的建議。您需要在暫停時保存剩餘的時間,並在計時器恢復時從該點繼續。至於什麼是錯了你當前的代碼:

Me.Interval = Me.Interval - sw.ElapsedMilliseconds 

上面的代碼將確保你繼續下一次它會工作打算的第一跳,但在continouos蜱你必須Me.Interval - sw.ElapsedMilliseconds作爲間隔而不是原始設置間隔。

-1

創建這樣一個計時器:

System.Timers.Timer t = new System.Timers.Timer(1000) 
    t.Elapsed += new System.Timers.ElapsedEventHandler(timerEvent); 

    public void timerEvent(object source, System.Timers.ElapsedEventArgs e) 
    { 

    } 

可以將此屬性設置爲啓動或暫停計時器執行timeEvent:

開始:

t.Enabled = true 

暫停:

t.Enabled = false 
0

這裏是我一直使用的是什麼。這可能不是最先進的準確,但工作很好。至少,對於試圖在計時器中暫停/恢復的人來說,這是一個很好的起點。

public class PausableTimer 
{ 
    private Timer _timer; 
    private Stopwatch _stopWatch; 
    private bool _paused; 
    private double _interval; 
    private double _remainingTimeBeforePause; 

    public PausableTimer(double interval, ElapsedEventHandler handler) 
    { 
     _interval = interval; 
     _stopWatch = new Stopwatch(); 

     _timer = new Timer(interval); 
     _timer.Elapsed += (sender, arguments) => { 
      if (handler != null) 
      { 
       if(_timer.AutoReset) 
       { 
        _stopWatch.Restart(); 
       } 

       handler(sender, arguments); 
      } 
     }; 

     _timer.AutoReset = false; 
    } 

    public bool AutoReset 
    { 
     get 
     { 
      return _timer.AutoReset; 
     } 
     set 
     { 
      _timer.AutoReset = value; 
     } 
    } 

    public void Start() 
    { 
     _timer.Start(); 
     _stopWatch.Restart(); 
    } 

    public void Stop() 
    { 
     _timer.Stop(); 
     _stopWatch.Stop(); 
    } 

    public void Pause() 
    { 
     if(!_paused && _timer.Enabled) 
     { 
      _stopWatch.Stop(); 
      _timer.Stop(); 
      _remainingTimeBeforePause = Math.Max(0, _interval - _stopWatch.ElapsedMilliseconds); 
      _paused = true; 
     } 
    } 

    public void Resume() 
    { 
     if(_paused) 
     { 
      _paused = false; 
      if(_remainingTimeBeforePause > 0) 
      { 
       _timer.Interval = _remainingTimeBeforePause; 
       _timer.Start(); 
      } 
     } 
    } 
}