Символ '+'
имеет особое значение в регулярном выражении. Это означает «соответствовать предыдущей вещи один или несколько раз», поэтому шаблон "Replace+txt"
будет соответствовать "Replacetxt"
или "Replaceetxt"
или "Replaceeetxt"
и т. Д.
Если вы хотите соответствовать буквальному символу '+'
, вам нужно экранировать его в своем шаблоне: "Replace\\+txt"
.
Я понял это сейчас, я уверен, что он не пуленепробиваемый, так что скажите мне, что с ним не так ...
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
Нет Pause (), вы можете написать тот, который в Pause ():
on Resume ():
Если вы пишете этот класс, опубликуйте его в ответе как похоже, что многим из нас нужна эта функциональность вне класса Timer. :)
Вы должны следовать совету Шей Эрличмен дал. Вам нужно будет сэкономить оставшееся время при приостановке и продолжить с того момента, когда таймер возобновится. Что касается того, что не так с вашим текущим кодом:
Me.Interval = Me.Interval - sw.ElapsedMilliseconds
Приведенный выше код гарантирует, что в следующий раз, когда вы возобновите работу, он будет работать так, как задумано, на первом тике, но на тиках континуума у вас будет Me.Interval - sw.ElapsedMilliseconds в качестве интервала вместо исходного установленного интервала.
На основе предыдущих комментариев от sveilleux2 и Tomerz, я улучшил решение реализовать IDisposable, позволить несколько вызовов резюме паузы, плюс добавляют свойства Enabled и Paused.
public class PausableTimer: IDisposable
{
private Timer _timer;
private Stopwatch _stopWatch;
private bool _paused;
private double _remainingTimeBeforePause;
public event ElapsedEventHandler Elapsed;
public PausableTimer()
{
_stopWatch = new Stopwatch();
_timer = new Timer();
_timer.AutoReset = false;
_timer.Elapsed += (sender, arguments) =>
{
Elapsed?.Invoke(sender, arguments);
if (_timer != null && _timer.AutoReset)
{
_stopWatch.Restart();
}
};
}
public PausableTimer(double interval): this()
{
Interval = interval;
}
public bool AutoReset
{
get
{
return _timer.AutoReset;
}
set
{
_timer.AutoReset = value;
}
}
public bool Enabled
{
get
{
return _timer.Enabled;
}
set
{
_timer.Enabled = value;
}
}
public double Interval
{
get
{
return _timer.Interval;
}
set
{
_timer.Interval = value;
}
}
public bool Paused
{
get
{
return _paused;
}
}
public void Start()
{
_timer.Start();
_stopWatch.Restart();
}
public void Stop()
{
_timer.Stop();
_stopWatch.Stop();
}
public void Pause()
{
if (!_paused && _timer.Enabled)
{
_paused = true;
_stopWatch.Stop();
_timer.Stop();
_remainingTimeBeforePause = Math.Max(0, Interval - _stopWatch.ElapsedMilliseconds);
}
}
public void Resume()
{
if (_paused)
{
_paused = false;
if (_remainingTimeBeforePause > 0)
{
_timer.Interval = _remainingTimeBeforePause;
_timer.Start();
_stopWatch.Start();
}
}
}
bool _disposed = false;
public void Dispose()
{
if (_timer != null && !_disposed)
{
// Not thread safe...
_disposed = true;
_timer.Dispose();
_timer = null;
}
}
~PausableTimer()
{
Dispose();
}
}