简体   繁体   中英

Using Multiple System.Timers in a Windows Service Issue

I have multiple timers in a windows service for some different stuff :

        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;

As you see, they have different intervals, but some times the operation takes time too long and 2 timers do work along side at the same time , and this is bad.

I try to use lock blocks to handle the issue :

 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();
            }
        }

But no change in action, and multiple timers do work at the same time. I want to prevent action of another timers if a timer doing a work.

If you only want one thing to happen at a time, then I'd suggest that instead of all of these timers, you just start one thread the runs the following pseudo-code.

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

The while(true) can be changed to a WaitOne(0) on a ManualResetEvent if that's your preferred way to signal to the thread to shut down, when the service is stopping.

And now, obviously, since there's only one thread that can call any of these functions, there's no need to use any other form of mutual exclusion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM