我正在开发Windows服务,我想每分钟从OnStart
调用一个方法。我最初有一个永远的while循环,但然后服务将无法安装。
while (true)
{
Stopwatch stopWatch = new Stopwatch();
int totalTime = 0;
stopWatch.Start();
MethodToCall();
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
totalTime = ts.Seconds * 1000 + ts.Milliseconds;
if (totalTime < 60000)
{
Thread.Sleep(60000 - totalTime);
//ManualResetEvent.WaitOne(10000);
}
else
{
Thread.Sleep(30000);
}
}
那么,我怎么能每分钟调用我的方法但是当方法超过一分钟时它将等待N分钟(假设30秒),然后通过调用方法重新开始。
答案 0 :(得分:1)
这样的事情应该有效。将AutoReset
标志设置为false,计时器将仅在指定的interval
时间后触发一次。在finally
块中,我们确保重新启动计时器倒计时,等待时间间隔再次过去。
var interval = TimeSpan.FromMinutes( 1 );
var timer = new System.Timers.Timer( interval.TotalMilliseconds ) { AutoReset = false };
timer.Elapsed += ( sender, eventArgs ) =>
{
var start = DateTime.Now;
try
{
// do work
}
finally
{
var elapsed = DateTime.Now - start;
if ( elapsed < interval )
timer.Interval = (interval - elapsed).TotalMilliseconds;
else
timer.Interval = TimeSpan.FromSeconds( 30 ).TotalMilliseconds;
timer.Start();
}
};
timer.Start();
Source for Timer.Elapsed
(note the bit about setting Interval
resetting the countdown)
答案 1 :(得分:0)
根据您的需要,有两种解决方案。你想每分钟做一次工作,总是等下一分钟吗?或者你想每分钟运行不超过一次但如果你落后就可以“赶上”?
换句话说,如果处理需要80秒,那么下一个工作是立即开始还是等到T = 120?
第一个更容易,但请注意,我没有对此进行测试,这只是一个指导原则:
AutoResetEvent waitHandle = new AutoResetEvent(false);
System.Timer(() => waitHandle.Set(), null, TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1));
while (true)
{
// Do stuff
waitHandle.WaitOne();
}
第二个有点困难。
ManualResetEvent waitHandle = new ManualResetEvent (false);
System.Timer(() => waitHandle.Set(), null, TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1));
while (true)
{
// Do stuff
waitHandle.Reset();
waitHandle.WaitOne();
}