C# 在同一个类中处理多个计时器的最佳方法是什么?
我在课堂上使用了几个计时器,想知道实现它的两个选项: 选项1: 每条消息都有自己的计时器C# 在同一个类中处理多个计时器的最佳方法是什么?,c#,.net,architecture,C#,.net,Architecture,我在课堂上使用了几个计时器,想知道实现它的两个选项: 选项1: 每条消息都有自己的计时器 class MessagesManager1 { Timer _timerA = new Timer(); Timer _timerB = new Timer(); Timer _timerC = new Timer(); public MessagesManager1() { _timerA.Interval = 1000; // 1 sec
class MessagesManager1
{
Timer _timerA = new Timer();
Timer _timerB = new Timer();
Timer _timerC = new Timer();
public MessagesManager1()
{
_timerA.Interval = 1000; // 1 sec
_timerB.Interval = 3000; // 3 sec
_timerC.Interval = 5000; // 5 sec
_timerA.Elapsed += _timerA_Elapsed;
_timerB.Elapsed += _timerB_Elapsed;
_timerC.Elapsed += _timerC_Elapsed;
_timerA.Start();
_timerB.Start();
_timerC.Start();
}
void _timerA_Elapsed(object sender, ElapsedEventArgs e)
{
// send message A
}
void _timerB_Elapsed(object sender, ElapsedEventArgs e)
{
// send message B
}
void _timerC_Elapsed(object sender, ElapsedEventArgs e)
{
// send message C
}
}
选项2:
仅使用一个计时器,根据SecondsCenter模数结果发送每条消息
class MessagesManager2
{
Timer _timer = new Timer();
public MessagesManager2()
{
_timer.Interval = 1000; // 1 sec
_timer.Elapsed += _timer_Elapsed;
_timer.Start();
}
int secondsCounter;
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
// send message A
if (secondsCounter % 3 == 0)
{
// send message B
}
if (secondsCounter % 5 == 0)
{
// send message C
}
}
}
哪一个更好,为什么?
(在性能、体系结构、维护、最佳实践等方面)。我认为这些都不是 你应该遵循单一责任原则——在你的两种选择中,同一个类执行不止一件事情 我将创建一个只有一个计时器的类,然后在运行时创建该类的3个实例,并将间隔值传递给构造函数 根据在经过的事件中需要执行的操作,您可以将
操作
委托传递给构造函数,或者创建派生类,用所需的行为重写抽象/虚拟方法
方法1
如果您知道您只需要处理这三件事,那么我认为最好将它们定义为编译时的显式行为:
public abstract class BaseTimerHandler
{
private readonly Timer m_Timer;
public BaseTimerHandler(int interval)
{
m_Timer = new Timer();
m_Timer.Interval = interval;
m_Timer.Elapsed += TimerElapsed;
m_Timer.Start();
}
protected abstract TimerElapsed(object sender, ElapsedEventArgs e);
//TODO unsubscribe from Elapsed in Dispose method.
}
public class TimerAHandler : BaseTimerHandler
{
private const int _INTERVAL = 1000;
public TimerAHandler() : base(_INTERVAL) { }
protected override TimerElapsed(object sender, ElapsedEventArgs e)
{
//send message A
}
}
public class TimerBHandler : BaseTimerHandler
{
private const int _INTERVAL = 3000;
public TimerBHandler() : base(_INTERVAL) { }
protected override TimerElapsed(object sender, ElapsedEventArgs e)
{
//send message B
}
}
public class TimerCHandler : BaseTimerHandler
{
private const int _INTERVAL = 5000;
public TimerCHandler() : base(_INTERVAL) { }
protected override TimerElapsed(object sender, ElapsedEventArgs e)
{
//send message C
}
}
方法2
如果您谈论的是具有可变数量的这些计时器(可能在运行时定义),那么我将注入行为,而不是定义显式类(如果需要发送方或事件参数,请调整操作
委托以包含参数)
这似乎有点过分,但我假设您的示例已简化。在这两种情况下,优点都是:
- 您可以对计时器处理进行单元测试,将其与要在运行时间中执行的实际代码分开(在BaseTimerHandler中,您可以为单元测试创建一个模拟派生类型,在TimerHandler中,您可以插入一个伪
)操作
- 您已经删除了计时器代码的重复,因此更易于维护并确保一致性
- 如果要在经过的过程中执行的代码还包含一些公共代码,则可以将BaseTimerHandler.TimeRecursed扩展为虚拟方法并添加此公共代码,或者对于TimerHandler,可以将TimeRecursed扩展为包含公共代码
public class TimerHandler
{
private readonly Timer m_Timer;
private readonly Action m_Elapsed;
public BaseTimerHandler(int interval, Action sendMessage)
{
if (sendMessage == null)
throw new ArgumentNullException("sendMessage", "Must provide send message");
m_Timer = new Timer();
m_Timer.Interval = interval;
m_Timer.Elapsed += TimerElapsed;
m_Elapsed = sendMessage;
m_Timer.Start();
}
private TimerElapsed(object sender, ElapsedEventArgs e){
{
m_Elapsed();
}
//TODO unsubscribe from Elapsed in Dispose method.
}
var timerA = new TimerHandler(1, () => { //send message A });
var timerB = new TimerHandler(3, () => { //send message B });
var timerC = new TimerHandler(5, () => { //send message B });