我有一个定期需要做一些工作的Windows服务。所以我设置了一个System.Timers.Timer来做到这一点。让我们假设处理时间可能大于计时器间隔。让我们假设如果发生这种情况将是一件非常糟糕的事情。
为了避免这种情况,我将Timer上的AutoReset设置为false,然后在我的进程中调用start。
public partial class Service : ServiceBase{
System.Timers.Timer timer;
public Service()
{
timer = new System.Timers.Timer();
//When autoreset is True there are reentrancy problme
timer.AutoReset = false;
timer.Elapsed += new System.Timers.ElapsedEventHandler(DoStuff);
}
protected override void OnStart(string[] args)
{
timer.Interval = 1;
timer.Start();
}
private void DoStuff(object sender, System.Timers.ElapsedEventArgs e)
{
Collection stuff = GetData();
LastChecked = DateTime.Now;
foreach (Object item in stuff)
{
item.Dosomthing(); //Do somthing should only be called once
}
TimeSpan ts = DateTime.Now.Subtract(LastChecked);
TimeSpan MaxWaitTime = TimeSpan.FromMinutes(5);
if (MaxWaitTime.Subtract(ts).CompareTo(TimeSpan.Zero) > -1)
timer.Interval = MaxWaitTime.Subtract(ts).TotalMilliseconds;
else
timer.Interval = 1;
timer.Start();
}
目前代码没有阻止,因为我知道它因为AutoReset = false而被顺序处理。但我可以做到这一点
lock(myLock)
{
Collection stuff = GetData();
LastChecked = DateTime.Now;
foreach (Object item in stuff)
{
item.Dosomthing(); //Do somthing should only be called once
}
}
编辑:澄清我的问题
我已经将服务设计为单线程,因此我不需要锁定。如果我添加锁定,我仍然在我的性能预算范围内,因此性能不是没有理由的。
基本上我正在权衡双方,我正在努力理清Right Thing™是什么。 在“无锁”方面,我依赖于对我的代码正确性的设计。在“锁定”方面,我将添加不必要的代码。
哪个更好?
答案 0 :(得分:2)
我要么全力保持线程安全,要么根本没有线程安全,只需在文档中写清楚该类是不是线程安全的。
最糟糕的事情是几年后回来,而不记得一切是否安全。然后你最终会浪费大量时间来调查你的代码,或者更糟糕的是,你最终会误导自己。
答案 1 :(得分:0)
如果多个线程将使用这些对象,则只需要lock
。在您的情况下,您的设计可以防止这种情况发生,因此无需锁定。
在这种情况下,添加锁定的唯一真正好处是可以防止以后更改调度算法时出现问题。
答案 2 :(得分:0)
TimeSpan maxInterval = new TimeSpan(0, 10, 0);
while(true)
{
DateTime startTime = DateTime.UtcNow;
//Do lots and lots of work
TimeSpan ts = DateTime.UtcNow - startTime;
ts = (ts > maxInterval ? new TimeSpan(0) : maxInterval-ts);
Thread.Sleep(ts);
}