I would like to have a timer for an ASP.net application that will kick off every Sunday night and perform something (update a table in the database). However, I really don't want to write up a service that has to be deployed on the server in addition to the web application. Is there a way to accomplish this easily? Perhaps using a Global.asax file?
It seems that the best solution was to use this technique. If I had more control over the server I would probably write up a console app to take advantage of scheduled tasks.
I'm not 100% sure where you would put it, but using a System.Threading.Timer would rock this.
// In some constructor or method that runs when the app starts.
// 1st parameter is the callback to be run every iteration.
// 2nd parameter is optional parameters for the callback.
// 3rd parameter is telling the timer when to start.
// 4th parameter is telling the timer how often to run.
System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(TimerElapsed), null, new Timespan(0), new Timespan(24, 0, 0));
// The callback, no inside the method used above.
// This will run every 24 hours.
private void TimerElapsed(object o)
{
// Do stuff.
}
Initially, you'll have to determine when to start the timer the first time, or you can turn the site on at the time you want this timer running on Sunday night.
But as others said, use something other than the site to do this. It's way easy to make a Windows service to deal with this.
I would write a console app and use Scheduled Tasks to schedule it.
Try the Quartz .NET, a job scheduler for .NET enterprise application such as ASP .NET and this should serve your purpose.
I don't think a .NET application is a good solution to your problem.
IIS Recycling will recycle the process every few hours (depending on the setting) and even if you set that interval to seven days, the application pool can still be recycled for other reasons beyond your control.
I agree with jcrs3: Just write a little console app and use scheduler. You can also write a service, but if you need something quick and easy, go with the console app.
In response to your comment about Scheduled Tasks:
Another hack would be to override an event in Global.asax, an even that is called often like Application_EndRequest() and do something similar to:
protected void Application_EndRequest()
{
if (((DateTime)Application["lastTimeRun"]) < DateTime.Today)
{
Application["lastTimeRun"] = DateTime.Today;
doSomething();
}
}
This would run after the first request after the date changed, so you wouldn't be guaranteed that this would be run precisely at 3:00 AM every morning.
I've even seed cases where you would hit the site using a Scheduled Task on another computer.
Related
I'm developing a MVC application and it has a method, which should have to run end of the day. I do not have the access to windows task scheduler and implementing windows service is not possible. (Because deployed package should have to give to different customers and they have their own servers. In this case we not gonna deploy windows service or use task scheduler)
Please tell me is there any method to execute some method at specific time.
I saw there are methods which are use timer. But the problem is this job should have to do only one time in the day and process will not take longer than 1 minute.
If we use timer, resources will allocate to timer service and it is not a good method as i guess, because this method run only one time in the day. (Process is running in other 23 hours and 59 minutes and it is wasting resources. I guess timer concept is ok, if process is running in every 5,10 minutes)
Please give me direction....
the best way is to use Quartz.Net
this is a good example to use it :
http://www.mikesdotnetting.com/article/254/scheduled-tasks-in-asp-net-with-quartz-net
I suppose that you already have a database. Create a table with a single datetime field named LastRun. Save in this field the last date and time your method has been executed.
In your MVC application on Session Start or on Application start compare LastRun datetime with current datetime and decide if you are going to perform the above mentioned method. After the method has been executed update the LastRun value.
how can you poll for example every 2 minutes inside a web application? I'm looking for something similar to a timer in winforms.
The poller class would be a singleton in the app (I use a container to handle lifecyles) and I'm also aware about the lifecycle of objects inside a webapp.
Web app code is not intended to run continuously for an indefinite time. It can be shut down or recycled by IIS based on various conditions multiple times an hour.
Better approach is to write a windows service or use scheduled tasks.
There are a lot of options. SignalR is a great framework to solve the polling problem that will gracefully fall back from WebSockets to Long Polling based on the support provided by the browser.
You have 2 options in JS
// easy
function run() {
// do stuff
}
setInterval(run, 120000)
// safer
function run() {
// do stuff
setTimout(run, 120000);
}
setTimout(run, 120000);
http://javascript.info/tutorial/settimeout-setinterval
set meta http-equiv refresh to the desired seconds in the .aspx page, the page will auto refresh as defined and you can update , for eg., Label.Text=DateTime.Now.Tostring(), to show the time. but as mentioned above its not always good practice to do this. for partial rendering you may rely on AJAX update panel
WebBackgrounder if you have small scale needs (this is easy to set up // minimal infrastructure).
Windows Service / Worker Role / Console App (that is executed as a periodic task) for serious work.
I m able to build a windows service and install it.
I m curious how can i run this service every hour ? I want it to run every hour periodically.
I also need to know the hour range that it s running so that I can store it somewhere.
How can i do that?
Edit : This service will be installed on many machines, therefore, I dont want to create a scheduled task say on 100 servers.
If you want a task to run on a regular interval as opposed to constantly, you should look into using the Task Scheduler.
If you need your code to be a service, but to be "activated" every hour, the easiest approach would be to make your service a COM object and have a simple task scheduled every hour that invokes a jscript/vbscript that creates your COM object and calls simple method on it.
The alternative is to use any of the wait APIs to "waste" an hour without consuming cycles.
Note that you also have to consider some interesting design decisions that depend on what your scenario is:
how is your service going to be started if it crashes or is stopped by the user?
if you are started after more than an hour, should you run again or do you need to wait to get on the exact hourly schedule?
how do you keep track of the last "activation" time if the timezone or the day-light saving time has changed while you were not active?
does your service prevent the computer from going to sleep/hibernate on idling or when the laptop cover is closed? if not, do you need to awake the computer on the hour to get your service working on your schedule?
Some of those are taken care of by the task scheduler, so I would strongly recommend going that route vs. waiting for an hour in your code.
You could create a scheduled task that runs every hour, to either run the service or send a message to "wake it up". Then, either pass in the current time in the scheduled task request, or just have your program pick up the current time when it wakes up.
Task Scheduler Managed Wrapper can help you set this up programmatically; you can google for other resources as well.
There are a couple options.
You could sleep for an hour.
You might be better suited for a Scheduled Task, not a service.
Thread.Sleep(1000*60*60);
Thread.Sleep(TimeSpan.FromHours(1));
code more readable this way
Thread.Sleep() solution will make sure that your service will run in one hour intervals, not every hour i.e. each task will be started at 1 hour + time to run the task. Consider using a Timer within your service. This will be a more robust solution since you have a control when to run a task, monitor its progress etc. Just remember that each Timer event will be fired in a different thread and if the task takes longer than one hour to run you might have to wait for the first task to finish to avoid concurrent tasks.
Task schedulers may be a good idea but services are designed to do this. Services gets installed easily and logs things properly. All you need to do is, at start of service, you can install a system timer (System.Threading.Timer) or there is also one more timer.
I want to have my website do a number of calculations every 10 minutes and then update a database with the results. How exactly do I set such a timer, i am assuming it would be in global.asax?
Doing something like that in a web application is somewhere between difficult and unstable to impossible. Web applications are simply not meant to be run non-stop, only to reply to requests.
Do you really need to do the calculations every ten minutes? I have found that in most cases when someone asks a question like this, they really just need the appearence of something running at an interval, but as long as noone is visiting the page to see the results, the results doesn't really need to be calculated.
If this is true in your case also, then you just need to keep track of when the calculations were done the last time, and for every request check if enough time has gone by to recalculate.
You'd be better off writing a separate non-UI application and then running that as a scheduled task.
Aside from (correct) statements about instability of web application for scheduled task execution, here's a strategy you could implement:
in global.asax, define application.onstart event in which create timer:
var dueTime = 5000;
var period = 5000;
var MyTimer = new Timer(new TimerCallback(MyClass.MyTaskProc), null, dueTime, period);
Application["MyTaskTimer"] = MyTimer;
this will pretty much take care of creating task and restarting it should application exit
ifs its strictly database calculations, keep it in the database. Create a stored proc that does what you want, then have SQL Server agent run that proc on a schedule.
the Cache solution in cagdas' answer works. I've used it. It's only downside is that it's difficult to turn it off if you need to suspend the timer for some reason. Alternate, but not quite identical solutions we've used.
Scheduled tasks in SQL Server
Scheduled windows tasks.
I really don't like schecduled tasks. I would rather put this function in a windows servic and throw a timer in it. With window services you can handle stop events very nicely. I do agree with everyone else, the web site is not the place for this.
How can I write a scheduler application in C# .NET?
You could also try Quartz.Net.
It all depends on your requirements:
If you have access to a database you use a table as a queue and a service to poll the queue at regular intervals.
If your application is client only (CLI) you can use the system scheduler ("Scheduled Tasks").
Lastly, if your application is only in a database (using the CLR in SQL Server 2005 for example) then you can create a SQL Server job to schedule it.
Assuming you're writing some system that needs to perform an action at a specific clock time, the following would cover the fundamental task of raising an event.
Create a System.Timer for each event to be scheduled (wrap in an object that contains the parameters for the event). Set the timer by calculating the milliseconds until the event is supposed to happen. EG:
// Set event to occur on October 1st, 2008 at 12:30pm.
DateTime eventStarts = new DateTime(2008,10,1,12,30,00);
Timer timer = new Timer((eventStarts - DateTime.Now).TotalMilliseconds);
Since you didn't go into detail, the rest would be up to you; handle the timer.Elapsed event to do what you want, and write the application as a Windows Service or standalone or whatever.
Write a windows service, there are excellent help topics on MSDN about what you need to do in order to make it installable etc.
Next, add a timer to your project. Not a Winforms timer, those don't work in Windows Services. You'll notice this when the events don't fire. Figure out what your required timer resolution is - in other words, if you have something scheduled to start at midnight, is it Ok if it starts sometime between Midnight and 12:15AM? In production you'll set your timer to fire every X minutes, where X is whatever you can afford.
Finally, when I do this I use a Switch statement and an enum to make a state machine, which has states like "Starting", "Fatal Error", "Timer Elapsed / scan for work to do", and "Working". (I divide the above X by two, since it takes two Xs to actually do work.)
That may not be the best way of doing it, but I've done it that way a couple of times now and it has worked for me.
You can try use Windows Task Scheduler API
You can also use the timer control to have the program fire of whatever event you want every X ticks, or even just one. The best solution really depends on what you're tring to accomplish though.