2009-04-14 5 views
6

Tôi đang xem cách tạm dừng System.Timers.Timer và tôi không thể tìm ra cách thích hợp để tạm dừng nó mà không cần đặt lại hẹn giờ.Cách thích hợp để tạm dừng một System.Timers.Timer?

Cách tạm dừng?

+0

Tôi sẽ về nhà trong khoảng 1 giờ để xem tôi đã nhận được câu trả lời nào .. – Fredou

+0

sw phải là _sw. –

+0

Tôi không biết liệu tôi có cập nhật Khoảng thời gian tạm dừng() hay không, tôi chỉ có thể giữ giá trị ở chế độ riêng tư. –

Trả lời

3

tôi đã nhận rằng bây giờ, tôi chắc chắn rằng nó không phải là chống đạn nên cho tôi biết những gì là sai với nó ...

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

Không có Pause(), bạn có thể viết một mà trên Pause():

  1. Thay đổi (Timeout.Infinite, Timeout.Infinite)
  2. Save the tính toán số lượng đếm thời gian còn lại.

trên Resume():

  1. Thay đổi (số lượng giờ còn lại)

Nếu bạn viết lớp này xin vui lòng gửi nó trong câu trả lời như nó có vẻ rằng nhiều người trong chúng ta cần chức năng ra khỏi lớp Timer. :)

+0

Tôi chỉ làm điều đó, bạn nghĩ sao? trở lại sau 1 giờ – Fredou

0

Bạn nên làm theo lời khuyên mà Shay Erlichmen đã đưa ra. Bạn sẽ cần phải tiết kiệm thời gian còn lại khi tạm dừng và tiếp tục từ thời điểm đó khi bộ hẹn giờ được tiếp tục. Đối với những gì là sai với mã hiện tại của bạn:

Me.Interval = Me.Interval - sw.ElapsedMilliseconds 

Đoạn mã trên sẽ đảm bảo rằng thời gian tiếp theo bạn khởi động lại nó sẽ làm việc như dự định trên đánh dấu lần đầu tiên, nhưng trên continouos ticks bạn sẽ phải Me.Interval - sw.ElapsedMilliseconds làm khoảng thời gian thay vì khoảng thời gian đã đặt ban đầu.

+0

xem phần cuối của lớp dành cho phụ riêng tư Sub ImprovedTimer_Elapsed – Fredou

-1

Tạo một bộ đếm thời gian như thế này:

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) 
    { 

    } 

bạn có thể thiết lập thuộc tính này để bắt đầu hoặc tạm dừng bộ đếm thời gian thực hiện timeEvent:

bắt đầu:

t.Enabled = true 

Pause:

t.Enabled = false 
+0

Tắt/Bật thực sự đặt lại hẹn giờ. Vì vậy, nếu khoảng thời gian hẹn giờ là 10 giây và bạn vô hiệu hóa nó sau 5 giây, khi bạn bật lại, nó sẽ bắt đầu lại sau 10 giây và không phải sau 5 giây. – sveilleux2

0

Dưới đây là những gì tôi đã sử dụng. Nó có thể không phải là nhà nước-of-the-nghệ thuật chính xác nhưng hoạt động khá tốt. Ít nhất, đó là một điểm khởi đầu tốt cho một người nào đó cố gắng tạm dừng/tiếp tục tại bộ đếm thời gian.

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(); 
      } 
     } 
    } 
} 
+0

Tôi biết hơi muộn nhưng ít nhận xét. 1. để hỗ trợ đa tạm dừng tiếp tục, hãy thêm _stopWatch.Khởi đầu(); vào Resume() sau _timer.Start(); 2. đối với các phiên bản .net trước v4.0 thay thế _stopWatch.Restart(); với _stopWatch = Stopwatch.StartNew(); 3. Tôi đã xóa ElapsedEventHandler khỏi hàm tạo và thêm sự kiện công khai ElapsedEventHandler Elapsed; để khớp với hành vi gốc. Cảm ơn bạn đã trích đoạn nội dung. nó thực hiện công việc. – Tomerz