我在课堂上使用了几个计时器,并想知道实现它的两个选项:
选项1:
每条消息都有自己的Timer。
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: 仅使用一个计时器并发送每个消息取决于secondsCounter模数结果。
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
}
}
}
哪一个更好,为什么? (在性能,架构,维护,最佳实践等方面)。
答案 0 :(得分:0)
我不会说那些。
你应该遵循单一责任原则 - 在你的两个选项中,同一个班级执行不止一件事。
我将创建一个具有单个Timer的类,然后在运行时创建该类的3个实例,并将间隔值传递给构造函数。
根据Elapsed事件中需要执行的操作,您可以将Action
委托传递给构造函数,或者创建覆盖具有所需行为的抽象/虚拟方法的派生类。
方法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
如果你正在谈论拥有可变数量的这些定时器,可能是在运行时定义的,那么我会注入行为而不是定义显式类(如果你需要发送者,可以调整Action
委托以包含参数事件args)。
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 });
这看起来有点像矫枉过正,但我假设你的例子是简化的。在这两种情况下,优点是:
Action
)