views:

171

answers:

5

I've searched on SO and found answers about Quartz.net. But it seems to be too big for my project. I want an equivalent solution, but simpler and (at best) in-code (no external library required). How can I do to call a method daily, at specific time?

I need to add some information about this:

  • the simplest (and ugly) way to do this, is check the time every second/minute and call the method, at right time

I want a more-effective way to do this, no need to check the time constantly, and I have control about whether the job is done a not. If the method fails (cause of any problems), the program should know to write to log/send a email. That's why I need to call a method, not schedule a job.

I found this solution http://stackoverflow.com/questions/2331736/call-a-method-at-fixed-time-in-java in Java. Is there a similar way in C#?

EDIT: I've done this. I added a parameter into void Main(), and created a bat (scheduled by Windows Task Scheduler) to run the program with this parameter. The program runs, does the job, and then exits. If a job fails, it's capable of writing log and sending email. This approach fits my requirements well :)

Thank you!

+10  A: 
  • Create a console app that does what you're looking for
  • Use the Windows "Scheduled Tasks" functionality to have that console app executed at the time you need it to run

That's really all you need!

Update: if you want to do this inside your app, you have several options:

  • in a Windows Forms app, you could tap into the Application.Idle event and check to see whether you've reached the time in the day to call your method. This method is only called when your app isn't busy with other stuff. A quick check to see if your target time has been reached shouldn't put too much stress on your app, I think...
  • in a ASP.NET web app, there are methods to "simulate" sending out scheduled events - check out this CodeProject article
  • and of course, you can also just simply "roll your own" in any .NET app - check out this CodeProject article for a sample implementation

Update #2: if you want to check every 60 minutes, you could create a timer that wakes up every 60 minutes and if the time is up, it calls the method.

Something like this:

using System.Timers;

const double interval60Minutes = 60 * 60 * 1000; // milliseconds to one hour

Timer checkForTime = new Timer(interval60Minutes);
checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed);
checkForTime.Enabled = true;

and then in your event handler:

void checkForTime_Elapsed(object sender, ElapsedEventArgs e)
{
    if (timeIsReady())
    {
       SendEmail();
    }
}
marc_s
I am way too slow :DGreat answer!
PieterG
Thought about it before. :). But my program will run continuously, and I want to know an alternative way, if there is :)
Vimvq1987
it's a Winform app. I'll try to convince my boss to change it design, but at first I should try to fill his requirements :p
Vimvq1987
Thank you for your answer. I added some information. I'm much appreciated if you can help ...
Vimvq1987
@Vimvq1987: updated my answer - again! :-)
marc_s
+2  A: 

The best method that I know of and probably the simplest is to use the Windows Task Scheduler to execute your code at a specific time of day or have you application run permanently and check for a particular time of day or write a windows service that does the same.

PieterG
A: 

If you want an executable to run, use Windows Scheduled Tasks. I'm going to assume (perhaps erroneously) that you want a method to run in your current program.

Why not just have a thread running continuously storing the last date that the method was called?

Have it wake up every minute (for example) and, if the current time is greater than the specified time and the last date stored is not the current date, call the method then update the date.

paxdiablo
+2  A: 

As others have said you can use a console app to run when scheduled. What others haven't said is that you can this app trigger a cross process EventWaitHandle which you are waiting on in your main application.

Console App:

class Program
{
    static void Main(string[] args)
    {
        EventWaitHandle handle = 
            new EventWaitHandle(true, EventResetMode.ManualReset, "GoodMutexName");
        handle.Set();
    }
}

Main App:

private void Form1_Load(object sender, EventArgs e)
{
    // Background thread, will die with application
    ThreadPool.QueueUserWorkItem((dumby) => EmailWait());
}

private void EmailWait()
{
    EventWaitHandle handle = 
        new EventWaitHandle(false, EventResetMode.ManualReset, "GoodMutexName");

    while (true)
    {
        handle.WaitOne();

        SendEmail();

        handle.Reset();
    }
}
Courtney de Lautour
+2  A: 

Whenever I build applications that require such functionality, I always use the Windows Task Scheduler through a simple .NET library that I found.

Please see my answer to a similar question for some sample code and more explanation.

Maxim Zaslavsky