Reputation: 2399
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
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
Reputation: 2806
You should monitor you service for performance. If you see there a performance problem:
System.Threading.Timer
is a simple, lightweight timer that uses callback methods and is served by threadpool threads.
System.Timers.Timer
for server-based timer
functionality. Maintainability and debug tips:
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
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
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