我需要实现
Timer
类来模拟倒计时时钟。计时器能够向订阅事件的其他类型发送带有有关 Started
、Tick
和 Stopped
事件信息的消息。我无法使用 .NET System.Timer 类来实现此实现。
Timer
类应具有以下功能:
- 当构造 Timer
类的对象时,必须对其进行赋值:
- 名称(不能为 null 或空字符串,否则应抛出异常 ArgumentException
);
- 刻度数(该数字必须大于 0;否则,应抛出异常 ArgumentException
)。
- 创建计时器后,应调用它来运行。为了响应 Run,计时器会触发 Started
事件。该事件应包含有关计时器名称和要触发的滴答数的信息。
- 触发 Started
事件后,计时器开始触发 Tick
事件,其中包含有关计时器名称和剩余触发时间的信息。 Tick
事件之间应该有延迟。要模拟 Tick
事件之间的延迟,建议使用 Thread.Sleep
方法。
- 在所有 Tick
事件被触发后,定时器必须触发 Stopped
事件,该事件应包含定时器的名称信息。
public class Timer
{
private string name;
private int numberOfTicks;
public Timer(string name, int numberOfTicks)
{
this.Name = name;
this.NumberOfTicks = numberOfTicks;
}
public event Action<string, int> Tick;
public event Action<string> Ticks;
public void OnStarted(Action<string, int> startDelegate)
{
this.Tick = startDelegate;
startDelegate?.Invoke(this.Name, this.NumberOfTicks);
}
public void OnStopped(Action<string> stopDelegate)
{
this.Ticks = stopDelegate;
stopDelegate?.Invoke(this.Name);
}
public void OnTick(Action<string, int> tickDelegate)
{
this.Tick = tickDelegate;
tickDelegate?.Invoke(this.Name, this.NumberOfTicks - 1);
}
public string Name
{
get => this.name;
set
{
this.name = value;
if (value == null || value.Length == 0)
{
throw new ArgumentException("Name is empty or null.", nameof(this.Name));
}
}
}
public int NumberOfTicks
{
get => this.numberOfTicks;
set
{
this.numberOfTicks = value;
if (value <= 0)
{
throw new ArgumentException("Number of ticks is less than zero.", nameof(this.NumberOfTicks));
}
}
}
}
public class TimerFactory
{
/// <summary>
/// Create an object of the <see cref="Timer"/> class.
/// </summary>
/// <param name="name">Name of timer.</param>
/// <param name="ticks">Count of ticks.</param>
/// <returns>A reference to an object of the <see cref="Timer"/> class.</returns>
public Timer CreateTimer(string name, int ticks)
{
Timer timer = new Timer(name, ticks);
return timer;
}
}
public class CountDownNotifier : ICountDownNotifier
{
private Timer timer;
/// <inheritdoc/>
public void Init(Action<string, int> startDelegate, Action<string> stopDelegate, Action<string, int> tickDelegate)
{
this.timer.OnStarted(startDelegate);
this.timer.OnStopped(stopDelegate);
this.timer.OnTick(tickDelegate);
}
/// <inheritdoc/>
public void Run()
{
}
}
public class CountDownNotifierFactory
{
/// <summary>
/// Create an object of the class that implements the <see cref="ICountDownNotifier"/> interface.
/// </summary>
/// <param name="timer">A reference to a class CustomTimer.</param>
/// <returns>A reference to an object of the class that implements the <see cref="ICountDownNotifier"/> interface.</returns>
/// <exception cref="ArgumentNullException">When timer is null.</exception>
public ICountDownNotifier CreateNotifierForTimer(Timer timer)
{
if (timer == null)
{
throw new ArgumentNullException(nameof(timer));
}
}
}
我对这项任务有疑问。我不知道如何纠正它。谢谢您的帮助。
在这里,我为您创建了
Timer
小班。我没有处理异常和其他事情,你会做的。我实现了多种创建计时器的方法。
要使用计时器,请编写:
Timer timer = new Timer("Some Name", 100, TimeSpan.FromSeconds(1));
timer.Started += OnTimerStarted;
timer.Tick += OnTimerTick;
timer.Stopped += OnTimerStopped;
timer.Start();
private void OnTimerStarted()
{
}
private void OnTimerTick()
{
}
private void OnTimerStopped()
{
}
或
Timer timer = new Timer("Some Name", 100, TimeSpan.FromSeconds(1), OnTimerStarted, OnTimerTick, OnTimerStopped); // This one will start timer immediately
或
Timer timer = Timer.Run("Some Name", 100, TimeSpan.FromSeconds(1), OnTimerStarted, OnTimerTick, OnTimerStopped); // This one will start timer immediately
public class Timer
{
#region Delegtes Definition
public delegate void OnStarted();
public delegate void OnTick();
public delegate void OnStopped();
#endregion
#region Delegates
public OnStarted? Started { get; set; }
public OnTick? Tick { get; set; }
public OnStopped? Stopped { get; set; }
#endregion
#region Properties
private string _name { get; set; }
private int _nTicks { get; set; }
private TimeSpan _tickTimeout { get; set; }
private DateTime _lastTick { get; set; } = DateTime.Now;
private bool __forceStop { get; set; } = false;
private bool _forceStop
{
get
{
return __forceStop;
}
set
{
if (value == true)
if (Stopped != null)
Stopped();
__forceStop = true;
}
}
private bool _started { get; set; } = false;
public string Name { get { return _name; } }
public int NumberOfTicks { get { return _nTicks; } }
public TimeSpan TickTimeout { get { return _tickTimeout;} }
#endregion
public Timer(string name, int numberOfTicks, TimeSpan tickTimeout)
{
_name = name;
_nTicks = numberOfTicks;
_tickTimeout = tickTimeout;
}
public Timer(string name, int numberOfTicks, TimeSpan tickTimeout, OnStarted startedHandler, OnTick tickHandler, OnStopped stopHanlder, bool autoStart = true)
{
_name = name;
_nTicks = numberOfTicks;
_tickTimeout = tickTimeout;
Started += startedHandler;
Tick += tickHandler;
Stopped += stopHanlder;
if (autoStart)
Start();
}
public void Start()
{
if (_started)
throw new Exception("Already started!");
_started = true;
Task.Run(() =>
{
// Running this delegate on separate thread so I do not stop tick for code inside to execute
if (Started != null)
Started();
});
Task.Run(() =>
{
_lastTick = DateTime.Now;
while (!_forceStop)
{
while (_lastTick.Add(_tickTimeout) > DateTime.Now)
{
if (_forceStop)
return;
Thread.Sleep(1);
}
Task.Run(() =>
{
// Running this delegate on separate thread so I do not stop tick for code inside to execute
if (Tick != null)
Tick();
});
_lastTick = DateTime.Now;
}
});
}
public void Stop()
{
_forceStop = true;
}
public Timer Run(string name, int numberOfTicks, TimeSpan tickTimeout, OnStarted startedHandler, OnTick tickHandler, OnStopped stopHanlder)
{
return new Timer(name, numberOfTicks, tickTimeout, startedHandler, tickHandler, stopHanlder);
}
}
同样的任务?你设法解决它了吗?我现在真的需要帮助..