Karthik
Karthik

Reputation: 2399

is timer efficient?

I have created an application that is used to read a mail box at certain intervals. If there is a new mail it downloads the attachment creates pdf files say 100 + combines it and mail it back to a particular list. Due to some server policies am in a position to convert it to a window service. I have used a timer my code given below

private System.Threading.Timer timer;
timer = new System.Threading.Timer(TimerTick, null, TimeSpan.Zero, TimeSpan.FromMinutes(1));

void TimerTick(object state)
{
  var minute = DateTime.Now.Minute;
  if (minute != lastMinute && minute % 5 == 0)
  {
    //check mail here
  }
}

Is implementing a timer like this an efficient way of doing this? Is there any better way to handle this? I am worried about the performance because the applications need to run 24 x7 and hence can end up in utilizing more cpu memory if inefficient.

is timer the only best available option in this scenario ?

Upvotes: 0

Views: 3607

Answers (4)

redcalx
redcalx

Reputation: 8637

System.Threading.Timer should be very lightweight in terms of CPU and memory usage, so I wouldn't envisage any problems there. More generally this sort of job is normally triggered by a scheduler that can be configured with more controlm with knowledge of things like weekend days, day of the month (e.g. do processing on first or last day of each month), etc.

If you do go down that route then check out Quartz.Net, an open source .net cron job scheduler.

Upvotes: 0

CodeTherapist
CodeTherapist

Reputation: 2806

You should monitor you service for performance. If you see there a performance problem:

  1. measure it
  2. change your code
  3. measure again
  4. than compare your measurments

System.Threading.Timer is a simple, lightweight timer that uses callback methods and is served by threadpool threads.

  • You might consider System.Timers.Timer for server-based timer functionality.

Maintainability and debug tips:

  • Use a XML config file to set the interval, without change your code. This will simply give you or administrators control about the service.

Use the code for easy debugging your service:

static void Main()
{
#if (!DEBUG)
    System.ServiceProcess.ServiceBase[] ServicesToRun;
    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
    System.ServiceProcess.ServiceBase.Run(ServicesToRun);
#else
    // Debug code: this allows the process to run as a non-service.
    // It will kick off the service start point, but never kill it.
    // Shut down the debugger to exit
    Service1 service = new Service1();
    service.EntryMethodHere(); // Your method that activates your timer
    // Put a breakpoint on the following line to always catch
    // your service when it has finished its work
    System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#endif 
}

Upvotes: 4

Casperah
Casperah

Reputation: 4554

The timer is very efficient, but maybe you should use TimeSpan.FromMinutes(5) instead and remove the inefficient conditionals in the TimerTick. Since the TimerTick will run in a ThreadPool thread, you will have to check that the previous event is finished before checking the mail server again.

private System.Threading.Timer timer = new System.Threading.Timer(TimerTick, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));

private bool FCheckingMails = false;
void TimerTick(object state)
{
    if (FCheckingMails) return;
    FCheckingMails = true;
    try
    {
        //check mail here
    }
    finally
    {
        FCheckingMails = false;
    }
}

Some may say that FCheckingMails is not threadsafe, but it really doesn't need to be.

If you are concerned about efficientcy you should check the code that runs millions of times/minute rather than the code that runs 12 times/hour.

Best luck with your quest.

Upvotes: 2

Kevin
Kevin

Reputation: 590

It would be more efficient to simply give the timer a 5 minute period, rather than a 1 minute period and checking the mail every 5th time.

timer = new System.Threading.Timer(TimerTick, null, TimeSpan.Zero, TimeSpan.FromMinutes(5)); 

Upvotes: 2

Related Questions