So, this question has been asked lots, and i have seen many different answers, but nothing finite or absolute for my scenario.
_
What I want to do:
We have a website, with a community of users.
In the admin section of the website, there are buttons to run the following functions:
Email all the users our weekly newsletter [Thursday 4pm],
message users that day's information [Daily 6pm],
post to facebook through facebook connect [Daily 8am and 6pm],
etc, etc. (There will be new requirements coming soon too, but they will follow the same principal)
_
All I want to do is to run these functions automatically, so a member of staff does not need to go to the website, login, then click each of the buttons at the set times.
That is, effectively, have the server click these buttons automatically, at the set times mentioned above.
_
I have seen suggestions for building a service with a timer built in, which will call each function, or use windows task scheduler, build an exe / com etc, but i get the gut feeling it should not be this complicated.
We have the code already written to actually do the tasks in a .net web page, and using some custom built classes etc.
I just do not know how to automatically call these functions at the desired times.
_
Server Info:
Dedicated server running Windows Web Server 2008 R2 (64bit)
Development Enviro:
Visual Studio 2010 SP1, using .NET 4.0
_
Thank you in advance for your help.
Kindest Regards,
Del
Splitting out the code into separate exes/dlls that can be called from the Windows task scheduler as well as your application is the way to go.
There's no sense in re-inventing a scheduler inside your application when one exists in the operating system you are running on. Particularly as your application is a web application which should be doing web things not server things.
The added advantage is that you have made your application more modular and easier to upgrade.
By definition, web servers respond to requests. This fundamental design manifests in all kinds of ways, such as application pools being shut down after a period of inactivity. For this reason, it is not a good idea to execute time-dependent code inside the context of a web server, because it is difficult to guarantee that the code will actually run (without jumping through a lot of hoops that have other negative side effects). Instead, an external time-dependent mechanism should send a request to the web server to execute these functions.
You said that you didn't want to use Windows Scheduler or write an external exe because "it shouldn't be this complicated"; but I don't see what's complicated about having a scheduled task call a web service.
Well, though I agree with other answers cheering for windows task scheduler and that website has nothing to do with scheduling tasks (it can be the source of input parameters, not the task runner itself), you could try using scheduling library like quartz.NET to schedule and run your necessary processes in the background.
Download cURL - a command-line HTTP request utility. Use this utility from task scheduler to call your web page / web service with the specific query string required to execute your functions.
http://curl.haxx.se/
This isnt very secure - anyone that knew the correct query string could cause these functions to execute - but it gives you the general idea. In my opinion its much safer to write a console app that uses your assemblies to directly execute your functionality. Call the console app from task scheduler.
Related
I'm new to this but I have a question: what is the best way, to run a function / process as background in C# ASP.NET MVC ?
For context, I'm creating a website for a project that does monitoring through snmp. The thing is that the various alerts have different timeouts between them. I want to go through all of alerts and see if the time between the last check and now is already passed. If so, the program will do another monitoring for that alert. It is supposed to run as background so it doesn't affect the rest of the site.
Can someone help me?
Thanks in advance ^^
Check this great article here: https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
TLDR: you have built in and third party options.
The built in is not as polished and with as many offerings as for example hangfire
The built in tries to delay the app pool recycle to finish the job.
Hangfire has good connectivity with redis and other persistence options
Both are not suitable for long running jobs, especially longer than the application pool restart period.
Both need some recovery mechanism in case the task is interrupted abruptly.
You can build an application running on a scheduler or a windows service or a linux cron job or even try something on the cloud as web jobs. Those are not related to the iis lifecycles and have none of the drawbacks mentioned above.
Once a day, I want my ASP.NET MVC4 website, which may be running on multiple servers, to email a report to me. This seems like a pretty common thing to want to do, but I'm having a tough time coming up with a good way to do it.
Trying to run a timer on a server to do this work is problematic for a couple of reasons. If I have multiple servers then I'd have the timer running on all of them (in case a server goes down); I'd need to coordinate between them, which gets complicated. Also, trying to access the database via Entity Framework from a background thread adds the complication that I must employ a locking strategy to serialize construction/disposal of the DbContext object between the periodic background thread and the "foreground" Controller thread.
Another option would be to run a timer on the servers, but to have the timer thread perform a GET to a magic page that generates and emails the report. This solves the DbContext problem because the database accesses happen in a normal Controller action, serialized with all of the other Controller accesses to the database. But I'm still stuck with the problem of having potentially more than one timer running, so I'd need some smarts in the Controller action to ignore redundant report requests.
Any suggestions? How is this sort of thing normally done?
You should not be doing this task from your web application as Phil Haack nicely explains it in his blog post.
How is this sort of thing normally done?
You could perform this task from a Windows Service or even a console application that is scheduled to run at regular intervals using the Windows Scheduler.
The proper solution is to create a background service that runs independently of your website. However, if that is not an option there is a hack where you can use the cache as explained in Easy Background Tasks in ASP.NET by Jeff Atwood.
A few options:
If you are hosting on Azure as a Website, check out WebJobs which was released recently in preview (http://azure.microsoft.com/en-us/documentation/articles/web-sites-create-web-jobs/)
If you don't want the pain of extracting out your email logic outside of the website, expose that functionality at a url (with a handler, mvc action, etc.) and then run a Windows Scheduled task that hits that url on a schedule.
Write a simple console app that is executed similarly via a Windows Scheduled task.
Or write a simple Windows Service that internally is looping and checking the time and when reached, hits that url, runs that exe, or has it's own code to send you the email.
I would recommend running Quartz.NET as a Windows Service:
Quartz.NET - Enterprise Job Scheduler for .NET Platform
There's boilerplate code for a Windows Service in the download.
I want to Scheduling in Asp.net
I have following options to implement this
To write SQLServer JOB(I dont want to do this.Dont want to go outside of .Net environment)
Second option is I will write windows service and this window service will call asp.net
webservice then this webservice calls asp.net method
(I also dont need to do this because my hosting provider might not be allow me to install
window service)
Third option is I call my scheduling method in Application_Start event in global class
(Drawback is, webserver will kill thread any time )
To call Scheduling Code in Page_Load event of Home Page(Might be nobody visits my website for hours
,Also page execution might be slow due to scheduling code)
I also found some online services that calls your page at given interval,some are given below
http://www.cronservice.co.uk/new/
http://scheduler.codeeffects.com
Anybody give me bettor solution of this and also explain why it is bettor?
Thanks in Advance
The ASP.NET application isn't the right place to implement scheduling. I would suggest creating a service or a scheduled task that runs in short intervals.
You don't have many options in a shared hosting environment. My host (WinHost) allows remote access to their database, so I was able to create an executable that ran on a local server with Task Scheduler.
The performance isn't great since the database is accessed over the internet, but it's still better than attempting to run pseudo scheduled tasks with ASP.NET.
Some hosts also offer a service that will request a url within your site on a scheduled basis. However, this didn't work for me because the task I had to run took longer than the request timeout.
There is no one solution that fits all. SQL jobs and windows jobs (scheduled thru windows task scheduler) are very widely used. In one of my previous work places they had jobs that ran on multiple platforms (mainframe,windows,sql server). Failure in some of these jobs, would cost in thousands by the day. So they employed something called ESP. This software monitored jobs on all platforms and sent a message to the control room in case of a failure.
If you throw some more light on the requirement, we might be able to help you better.
ASP.NET is not the right place to house your Scheduled Tasks. I'm using Quartz.net when I have to create Scheduled Tasks.
Create a page that launches your task and place it at the URL http://www.mydomain.com/runtask.
Create a scheduled task on your home PC that sends a request to http://www.mydomain.com/runtask.
You'll need to keep your home PC on all the time.
Ideally I would go with number 1 as you get full control/history/error reporting etc. You can write an SSIS job in .NET and have SQL server schedule it.
However, I have had a similar problem with shared hosting that is very restrictive. What I did was create a page which runs the process on page load (using validation in the querystring for security). I then used a machine I have which is always on to schedule a Windows Task Scheduler (this is part of Windows as standard) to call a bit of VB script that opens the browser and then shuts it.
I am developing a solution in .Net utilising the VMWare Web Service API to create new isolated virtualised development environments.
The front end will be web based. Requestors input details for the specific environment which will be persisted to SQL. So I need to write an engine of some sort to pull the data from SQL and work on the long running task of creating resource pools, switch port groups and cloning existing VM templates etc. As work progresses, events will be raised to write logs and update info back to SQL. This allows requestors to pull data back into a webpage to see how it's progressing or if it's completed.
The thing I am struggling with is how to engineer the engine which will exec the long running task of creating the environment. I cannot write a windows service (which I would like) as we work in a very secure environment and it's not possible (group policy etc). I could write a web service to execute the tasks, extending the httpRuntime executionTimeout to allow the task to complete. But I'm keen to hear what you guys think may be a better solution to use (based on .Net 3.5). The solution needs to be service oriented as we may be using it on other projects within our org. What about WWF, WCF? I have not used any of the newer technologies available since .Net 2.0 as we've only just been approved to move up from .Net 2.0.
First of all, a Windows Service isn't insecure. One of software development devils is discarding a solution by ignorance or because a lack of investigation, requirement analysis and taking decisions collaborately.
Anyway, if you want to do it in a SOA way, WCF is going to be your best friend.
But maybe you can mix a WCF service hosted by Internet Information Services and Message Queue Server (MSMQ).
A client calls a WCF service operation and enqueues a message to some Message Queue Server queue. Later, a Windows scheduled task executed overtime, checks if your queue has at least an incoming message, and task processes this and others until you dequeue all messages.
Doing this way, IIS WCF host will never need to increase its execution time and it'll serve more requests, while the heavy work of executing this long tasks is performed by a Windows scheduled task, for example a console application or a PowerShell cmdlet (or just a PowerShell script, why not?).
Check this old but useful MSDN article about MSMQ: http://msdn.microsoft.com/en-us/library/ms978430.aspx
I don't understand your comment regarding services being insecure, I think that is false.
However I would look into creating something that uses a messaging bus/daemon.
RabbitMQ: http://www.rabbitmq.com/
MassTransit: http://masstransit-project.com/
NServiceBus: http://nservicebus.com/
Then you can basically use something like WCF, Console App or Service as your daemon.
I have a requirement that a Windows Forms C# .NET 2.0 program running in user-space (not a service) must always be running. As I'm not infallible and make coding mistakes, I wanted to know of any extra safeguards I could use to ensure this requirement is met. The things I've been thinking of are TaskScheduler to check it every 5 minutes, A stub watcher or a secondary process. Are these good / bad ideas?
Thanks,
Richard
EDIT: The reason I didn't use a service (the obvious and sensible answer!) was the program runs in a kiosk type environment and has has a heavy GUI component. The service option didn't work well across Windows 2000 - W7.
EDIT: The second reason not to use a service was the app needs internet access and on some of our customer sites, proxies are set up to only allow specific users (not the local system account) so it would be tricky to ensure access if multiple users log onto the machine.
Task scheduler is a cheap solution for this which does work. I use this to keep our Perforce Proxy server running (had some issues with the service), and so far there's been no problems - though now I've said that the server's probably exploded!
However, the most complete solution is a Windows service which invokes your app. You can make that service catch error return codes from the app, restart it on failure and notify you by email, which may help you diagnose and fix those issues. I think the Task Scheduler does something similar but it won't be able to provide as much insight into your application as a custom service.
If you're unsure of how to do that, then something like this should work:
http://www.codeproject.com/KB/install/csharpsvclesson1.aspx
There are three approaches that you can take:
Heartbeat Message.
A heartbeat is useful in a distributed application and is simply message that is sent (from let say a client to server) to confirm that it is still healthy/running.
Manager Process
A stub program, implemented as either a user process or a service. It launches the main application, monitors any unhandled exceptions, reports errors, and restarts on failure.
An exception guard on the entry point.
A try-catch-all in the application entry point.
I would recommend either of the first two options; the third option, the try-catch-all, is a particular nasty hack for the lazy and inexperienced programmer (IMHO).
I have successfully used both heartbeat and manager process in a large distributed application.
UPDATE
As for ready-to-go™ restart managers, take a look at the Windows API Codepack as discussed in Emmanuel Istace blog post (http://istacee.wordpress.com/2013/09/21/automatic-recovery-restart-in-net-application/).
You can install the package from https://www.nuget.org/packages/WindowsAPICodePack-Core/