views:

71

answers:

4

Hi,

I have a Service that hits a database every 10 sec and gets the data if there is any. The thing is that processing this data can take up to 30 sec. If I use a Timer with 10 sec interval the service will get the same data twice.

The effect i´m trying to achieve(Just for visualization):

while(true)
{
    if(Getnrofrows() > 0)
      do stuff
    else
      sleep for 10 sec
}

Ppl saying Thread.Sleep is a bad idea in production services, how do I do this with timers?

/mike

+3  A: 

Did you try to set Timer property auto reset to false, and enabling timer again when process of refreshing data is over

using System;

public class PortChat
{
    public static System.Timers.Timer _timer;
    public static void Main()
    {

        _timer = new System.Timers.Timer();
        _timer.AutoReset = false;
        _timer.Interval = 100;
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
        _timer.Enabled = true;
        Console.ReadKey();
    }

    static void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        //Do database refresh
        _timer.Enabled = true;
    }
}
adopilot
Exactly what I was looking for. Thx!
Mike Ribeiro
Sorry but shouldnt it be _timer.Enabled = false in the elapsed event? Why is it set to true again if its done in main?
Neale
@Neale, The original question was about pausing loop until something is not finished. When we put _timer.Autoreset = false then loop will occur only once after enabling timer. So when our loop ends with reading we will activate again timer by enabling it
adopilot
A: 

There is nothing wrong with this approach. A sleeping thread does not consume any CPU cycles.

If you need to do something exactly every X seconds, a timer is the way to go. If, on the other hand, you want to pause for X seconds, then Thread.Sleep is appropriate.

Winston Smith
+1  A: 

I don't see any problems with using Sleep at all other than you might end up with ugly code.

To answer your question:

public class MyTest
{
    System.Threading.Timer _timer;


    public MyTest()
    {
       _timer = new Timer(WorkMethod, 15000, 15000);
    }


    public void WorkMethod()
    {
       _timer.Change(Timeout.Infinite, Timeout.Infinite); // suspend timer

       // do work

       _timer.Change(15000, 15000); //resume

    }
}
jgauffin
A: 

Thread.Sleep is not bad in itself in a service, just that you need to be responsive to service commands, so your worker thread should not go to sleep for an hour, but rather needs to sleep for short periods of time and then wake up and listen if the service controller part of the service is telling it to stop for some reason.

You want to make it so that if the admin tells your service to stop, it'll stop quickly enough so that it won't get any timeout messages where the admin can't be sure that your service is stopped and it's safe to reboot the machine or similar.

ho1