【问题标题】:Using Multiple System.Timers in a Windows Service Issue在 Windows 服务问题中使用多个 System.Timers
【发布时间】:2014-07-22 09:46:32
【问题描述】:

我在 Windows 服务中有多个计时器用于一些不同的东西:

        timerForUpdate = new Timer();
        timerForSyncByServer = new Timer();
        timerForGetFactors = new Timer();
        timerForDelete = new Timer();
        timerForHandshaking = new Timer();
        timerForConfig = new Timer();

        timerForSyncByServer.Interval = 35000;
        timerForUpdate.Interval = 40000;
        timerForDelete.Interval = 30000;
        timerForGetFactors.Interval = 200000;
        timerForHandshaking.Interval = 60000;
        timerForConfig.Interval = 10000;

如您所见,它们有不同的间隔,但有时操作时间太长,并且 2 个计时器同时工作,这很糟糕。

我尝试使用lock 块来处理问题:

 public object CrossTimer = new object();
 void timerForConfig_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (CrossTimer)
            {
                ConfigOperation.UpdateWebConfig();
            }
        }

        void timerForHandshaking_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (CrossTimer)
            {
                HandshakeOperations.ShakeHand();
            }
        }

        void timerForDelete_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (CrossTimer)
            {
                FoodTypesOperations.DeleteWebDB();
                KalaToleedOperations.DeleteWebDB();
            }
        }
        void timerForGetFactors_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (CrossTimer)
            {
                FactorOperations.GetLastFactors();
            }
        }

但是动作没有变化,并且多个计时器确实同时工作。 如果计时器正在工作,我想阻止其他计时器的操作。

【问题讨论】:

  • 区间不同,但有时多个区间是相同的。例如。在120000 之后,UpdateDeleteHandshake 计时器将同时触发。那你想发生什么?
  • @Damien_The_Unbeliever 完全正确,我想如果在工作中握手,删除等到工作结束

标签: c# multithreading timer windows-services


【解决方案1】:

如果您只想一次发生一件事,那么我建议您不要使用所有这些计时器,而只需启动一个线程来运行以下伪代码。

Initialize count to 0
Initialize rundate to Now()
While(true)
    count++
    if(count==840) count = 0
    if(count%7==0) DoSyncByServer()
    if(count%8==0) DoUpdate()
    if(count%6==0) DoDelete()
    if(count%40==0) DoFactors()
    if(count%12==0) DoHandshake()
    if(count%2==0) DoConfig()
    rundate += 5 seconds
    interval = Now() - rundate
    if(interval > 0)
       sleep(interval)
    end if
end while

while(true) 可以更改为 ManualResetEvent 上的 WaitOne(0),如果这是您在服务停止时向线程发出信号以关闭的首选方式。

现在,显然,由于只有一个线程可以调用这些函数中的任何一个,因此无需使用任何其他形式的互斥。

【讨论】:

  • 感谢您的回答,您的解决方案很好,但为什么锁块在计时器中不起作用?
  • @SamanGholami - 他们应该,如果没有你所有的代码(我不会要求你)并且能够运行/测试/调试它,很难确定它为什么不起作用.但似乎你通过拥有多个计时器来引入所有这些潜在的并发性,然后投入更多的工作来消除并发性——这就是为什么我一开始就不引入它的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多