System.Timers.Timer
を一時停止する方法を見ていて、タイマーをリセットせずに一時停止する方法がわかりません。System.Timers.Timerを一時停止する適切な方法?
一時停止の仕方は?何の一時停止はありません
System.Timers.Timer
を一時停止する方法を見ていて、タイマーをリセットせずに一時停止する方法がわかりません。System.Timers.Timerを一時停止する適切な方法?
一時停止の仕方は?何の一時停止はありません
私は
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
は()、あなたが書くことができる1そのポーズ()上:
():
あなたはこのクラスを記述する場合、私たちの多くは、その機能を必要とするように見えるような答えでそれを投稿してくださいTimerクラスから外します。 :)
私はちょうどそれをやった、あなたはどう思いますか? 1時間後に戻す – Fredou
あなたはShay Erlichmenの助言に従うべきです。一時停止するときの残りの時間を保存し、タイマーが再開された時点から続行する必要があります。
Me.Interval = Me.Interval - sw.ElapsedMilliseconds
上記のコードは最初の目盛りの上に意図したとおりに、あなたが再開する次回は、それが動作することを確認して、しかしcontinouosにあなたはMe.Intervalがあるでしょうティックます:あなたの現在のコードと間違っている何のためとして、 - 元の設定間隔ではなく、間隔としてsw.ElapsedMilliseconds。
サブプライベートSub ImprovedTimer_Elapsed – Fredou
は、このようなタイマーを作成します...今のところ、私はそれはそれで間違っているものを私に教えてくれ防弾ではないと確信しているということだ:
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
を無効にする/有効にすると、実際にタイマーがリセットされます。したがって、タイマー間隔が10秒で、5秒で無効にすると、有効にすると、5秒からではなく10秒から戻ってきます。 – sveilleux2
ここでは、私が使用してきたものです。それは、最先端の正確さではないかもしれないが、かなりうまくいく。少なくとも、それはタイマーで一時停止/再開しようとする人にとっては良い出発点です。
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();
}
}
}
}
私はそれが少し遅れたが、いくつかのコメントを知っています。 1.マルチポーズレジュームをサポートするには、_stopWatchを追加します。開始(); _timer.Start()の後にResume()に追加します。 2. .net以前のバージョンのv4.0では、_stopWatch.Restart()を置き換えます。 _stopWatch = Stopwatch.StartNew(); 3.コンストラクタからElapsedEventHandlerを削除し、パブリックイベントElapsedEventHandler Elapsedを追加しました。 を元の動作に合わせます。 スニペットありがとうございます。 それは仕事をします。 – Tomerz
私は返信を見るために約1時間後に戻ってきます。 – Fredou
swは_swでなければなりません。 –
Pause()でIntervalを更新するかどうか分かりませんが、プライベートで値を保持することができます。 –