在SO上有很多关于C#System.Threading.Timer
的问题,但我找不到这个确切的问题。
在我们的代码中,我们需要确保计时器在后触发,我的意思是在给定的时间后触发。如果计时器提早启动.00001秒,那就不好了。另一方面,如果计时器甚至会延迟几秒钟,那就没问题了。
我让this dotnetfiddle显示计时器有时会提前触发。运行几次,你就会看到它(或者在代码中增加numSamples
)。在我的本地PC上,我检查了其他时间跨度并且它们的行为相似,但是dotnetfiddle不允许您的代码执行太长时间,因此TimeSpan.FromSeconds(1)
是该演示中的内容。< / p>
一种黑客的方式,我认为只是睡了十分之一秒,这似乎可以解决Timer
不准确的模糊问题。 是否有规范方法确保在给定时间之后实际触发?我知道C#中有more accurate timers,但由于我们的要求允许在适当的时间之后有些摆动的房间我觉得可能会有更便宜的东西被我忽略了。
感谢@PaulF和@AlexeiLevenkov的意见。我想我成了XY问题的受害者。我主要担心的是潜在的基本事实&#34;对于我在代码中工作的时间是DateTime
的时间。试图准确一个关于不准确的事实的计时器&#34;是有缺陷的。我给出了我在下面提出的答案,将来会接受它。
答案 0 :(得分:0)
ElaptseHandler使用thread.Sleep(100)或您认为适合的任何数量来延迟代码的实际执行
Timer timer = new Timer(1000);
timer.Elapsed += async ( sender, e ) => await HandleTimer();
timer.Start();
private static Task HandleTimer()
{
Thread.Sleep(100);
//YOUR CODE HERE
}
答案 1 :(得分:0)
为什么不使用quarzt.net here我已经习惯了,并且使用金块很容易实现。
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("myJob", "group1")
.Build();
// Trigger the job to run now, and then every 40 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("myTrigger", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(40)
.RepeatForever())
.Build();
sched.ScheduleJob(job, trigger);
取自网站http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/using-quartz.html
答案 2 :(得分:0)
在Timer
处理程序的内部,我在下面放了一段代码。这不是我想要做的,但考虑到DateTime
是我需要确保我在处理程序的主体之后,这是我能想到的最好的。
private static void handler()
{
// because I can handle a few second delay,
// a delay of 1 second is acceptible to me
while(DateTime.Now > _waitForThisDateTime) Thread.Sleep(1000);
//Handler body here
}
来自@PaulF和@AlexeiLevenkov的评论指出,试图准确地确定关于不准确DateTime
的时间是有缺陷的,所以我不认为有更好的答案。 &#34;修复&#34;从长远来看,我将完全改变现有的代码,以达不到给定DateTime
之后的要求!
另外,Timer
似乎越不准确传递给它的TimeSpan
越长。我们的时间跨度大约为1天,因此我看到的错误比我在OP中提供的演示要大。