怎么防止System.Timers.Timer在线程池上排队执行?标准System.Timers.Timer行为存在问题。计时器会在某个时间间隔引发Elapsed事件。但是当Elapsed事件处理程序内部的执行时间超过定时器间隔时,线程池开始排队事件处理。这是我的问题。这是因为使用我的Elapsed事件处理程序,我从数据库中获取一些数据并对其进行处理,最后将结果保存回数据库。但数据处理应该只提供一次。那么,有没有一种方法可以防止排队System.Timers.Timer的elapse事件。作为此问题的示例,您可以考虑下一个测试程序:.现在,Thread.CurrentThread.ManagedThreadId);线程.睡眠(20000);}staticvoidMain(string[]args){Console.WriteLine("Pressforfinishingnn");ThreadPool.SetMaxThreads(10,10);System.Timers.TimerMyTimer=newSystem.Timers.Timer(1000);MyTimer.Elapsed+=newElapsedEventHandler(TimeProc);MyTimer.Start();控制台.ReadLine();我的计时器停止();可能的输出如下:当前时间03.02.20110:00:09在线程上4当前时间03.02.20110:00:10在线程上5当前时间03.02.20110:00:12在线程上6当前时间03.02.20110:00:13在线程上7当前时间03.02.20110:00:14在线程上8当前时间03.02.20110:00:15在线程上9当前时间03.02.20110:00:16在线程10当前时间03.02.20110:00:17在线程11当前时间03.02.20110:00:18在线程上12当前时间03.02.20110:00:19在线程上13当前时间03.02.20110:00:30在线程上4当前时间03.02.20110:00:30在线程上5可能的解决方案场景:1)灵感来自于:C#TimervsThreadinService上面例子的代码如下:publicclassEntryPoint{privatestaticSystem.Timers.TimerMyTimer;privatestaticvoidTimeProc(objectstate,ElapsedEventArgse){Console.WriteLine("线程{1}上的当前时间{0}",DateTime.Now,Thread.CurrentThread.ManagedThreadId);线程.睡眠(20000);MyTimer.Enabled=true;}staticvoidMain(string[]args){Console.WriteLine("Pressforfinishingnn");ThreadPool.SetMaxThreads(10,10);MyTimer=newSystem.Timers.Timer(1000);MyTimer.AutoReset=false;MyTimer.Elapsed+=newElapsedEventHandler(TimeProc);MyTimer.Enabled=true;控制台.ReadLine();}}2)第二种方式是关于SynchronizingObject的,但它只对Windows窗体应用程序有价值,或者需要额外的开发代码来实现一个将实现ISynchronizeInvoke接口的对象更多关于这种方式你可以在这里找到所以,现在我更喜欢第一个解决方案。在这种情况下,我通常做的是在Elapsed处理程序开始时停止计时器,并在结束时再次启动它。这样,您一次只能处理一个订单号。更新:根据MSDN链接,我认为他们的意思是您可以设置自己的标志(并且仍然有勾号),但还应该考虑线程安全。我会说简单地停止它,然后在执行这么长时间后启动它。tmr.停止();//你冗长的执行代码在这里tmr.Start();您看到的行为是设计使然。在定时器上设置SynchronizingObject,或使用另一个不在多线程上计时的定时器(例如System.Threading.Timer)。我只是创建一个静态标志变量。这样我的计时器就会继续运行,但如果该方法在下一个计时器周期之前没有完成,则会绕过代码。在用于计时器的方法中,测试事件是否在进行中。Timer_Method_Called(){if(eventInProgress==0){//将事件标记为正在进行eventInProcess==1;//执行代码....//代码完成后,允许方法执行eventInProgress==0;}}由于没有一个答案是线程安全的,让我提出一个:setTimerBodyRunning必须是线程安全的//此处执行长时间运行的操作setTimerBodyFinished();如您所见,计时器处理程序首先检查它是否尚未运行,只有在返回false时才输入文本。如果返回true,处理程序会快速返回并且滴答不会排队(它们将使用简单的锁定语句)。以下是setTimerBodyRunning和setTimerBodyFinished的定义:privateboolsetTimerBodyRunning(){boolretVal=false;lock(timerBodyRunning){//timerBodyRunning是类型对象,它包含一个布尔值。//它是对象而不是布尔值的原因是它可以被锁定以确保线程安全if(!((bool)timerBodyRunning)){timerBodyRunning=true;retVal=真;}}返回retVal;}privatevoidsetTimerBodyFinished(){lock(timerBodyRunning){timerBodyRunning=false;下面是初始化和启动定时器的方法:以上是C#学习教程:如何防止System.Timers.Timer在线程池上排队执行?如果分享的内容对你有用,需要了解更多C#学习教程,希望大家多多关注——objecttimerBodyRunning=newobject();timerBodyRunning=false;System.Timers.TimertimerFrequency100MS=新的System.Timers。定时器();timerFrequency100MS.Interval=FREQUENCY_MS;//它将每100毫秒触发一次timerFrequency100MS.Elapsed+=newSystem.Timers.ElapsedEventHandler(oneHundredMS_Elapsed);timerFrequency100MS.Start();本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
