Sprawdzam, jak zatrzymać się na System.Timers.Timer
i nie mogę znaleźć prawidłowego sposobu na zatrzymanie go bez resetowania licznika czasu.Właściwy sposób wstrzymania System.Timers.Timer?
Jak zatrzymać?
Sprawdzam, jak zatrzymać się na System.Timers.Timer
i nie mogę znaleźć prawidłowego sposobu na zatrzymanie go bez resetowania licznika czasu.Właściwy sposób wstrzymania System.Timers.Timer?
Jak zatrzymać?
mam, że na razie, jestem pewien, że to nie jest kuloodporny więc powiedz mi, co jest nie tak ...
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
Nie ma pauzy(), można napisać, że jeden na Pause():
na Resume():
Jeśli piszesz tej klasy proszę umieszczać go w odpowiedzi, jak wydaje się, że wielu z nas potrzebuje tej funkcjonalności z klasy Timer. :)
Po prostu to zrobiłem, jak myślisz? powrót w 1 godzinę – Fredou
Powinieneś przestrzegać wskazówek udzielonych przez Shay Erlichmen. Będziesz musiał zaoszczędzić czas pozostały do zatrzymania i kontynuować od tego momentu, gdy timer zostanie wznowiony. Jeśli chodzi o to, co jest nie tak z bieżącego kodu:
Me.Interval = Me.Interval - sw.ElapsedMilliseconds
Powyższy kod będzie upewnić się, że następnym razem, gdy wznowienie będzie działać zgodnie z przeznaczeniem na pierwszym kleszcza, ale na continouos kleszcze musisz Me.Interval - sw.ElapsedMilliseconds jako interwał zamiast pierwotnego ustawionego interwału.
spójrz na koniec klasy dla sub Prywatne Sub ImprovedTimer_Elapsed – Fredou
Tworzenie timer tak:
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)
{
}
co możliwe ustawić tę właściwość, aby uruchomić lub zatrzymać timer wykonać TimeEvent:
start:
t.Enabled = true
Pauza:
t.Enabled = false
Wyłączenie/Włączenie faktycznie resetuje timer. Jeśli więc interwał czasowy wynosi 10 sekund, a wyłączysz go po 5 sekundach, po ponownym włączeniu zacznie działać od 10 sekund, a nie od 5 sekund. – sveilleux2
Oto co używam. Być może nie jest to najnowocześniejsza dokładność, ale działa całkiem nieźle. Przynajmniej jest to dobry punkt wyjścia dla kogoś, kto próbuje wstrzymać/wznowić działanie timera.
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();
}
}
}
}
Wiem, że jest trochę późno, ale kilka komentarzy. 1. Aby obsługiwać multi pause-resume, dodaj _stopWatch.Początek(); do wznowienia() po _timer.Start(); 2. dla wersji .net przed wersją 4.0 zastąpić _stopWatch.Restart(); z _stopWatch = Stopwatch.StartNew(); 3. Usunąłem ElapsedEventHandler z konstruktora i dodałem publiczne wydarzenie ElapsedEventHandler Elapsed; , aby dopasować oryginalne zachowanie. Dzięki za urywek. wykonuje zadanie. – Tomerz
Wracam do domu, więc wracam za około godzinę, żeby zobaczyć, co mam odpowiedź. – Fredou
sw powinno być _sw. –
Nie wiem, czy zaktualizowałbym interwał w pauzie(), po prostu mógłbym zachować wartość jako prywatną. –