问题
I have an ASP.NET forms app that allows users to run some management reports. Some reports need to be run unattended on a schedule and I created a C# console app to run them in Task Scheduler on a server. The powers that be are adamant that there be one web based app that does it all.
How do you reliably run jobs on a schedule, say 11:00PM daily, from a web app? I see Quartz.net as an option for the scheduler, but how do you keep a web page up 24/7?
Thanks
回答1:
Regardless of what the powers that be say, you shouldn't rely on an ASP.NET app to be a scheduler. Have a dedicated service in the backend that retrieves the schedule from a shared database that the ASP.NET web app writes to (directly or via a data layer) and have it spawn the reports.
This approach
avoids reliability issues: IIS worker processes may be recycled at any time - you would have to account for that which adds complexity.
limits possible security limitations: You would have to add certain permissions to the IIS AppPool identity to allow spawning of these processes. It's better to limit the rights as much as possible to reduce the attack surface.
回答2:
Running scheduled tasks from a web application doens't make any sense whatsoever. Either create a service that runs on the server, or schedule a task to run at certain intervals via the Task Scheduler.
Not to sound indelicate here, but whoever suggested that this should be done through a web application clearly does not understand the limitations of the technology.
回答3:
You take the smug route:
Write the reports that need to be run unattended to a HttpHandler
Then write a service that periodically targets the service.
Then you say, "See! I met your requirements. All the reports are run within the asp.net web page like you asked." -- You just added something in addition =P
Side comment: You should try and demonstrate why their requirements are not realistic.
回答4:
You can make IIS keep an app pool up 24x7 without too much trouble -- just disable the timeout and the automated recycling. Then something like quartz could work.
That said, your management is not making much sense, I would try and hunt down why they want to do it in a single app and start knocking down objections in a rational manner.
回答5:
While doing this on a website is not ideal or recommended..it is possible, given that the site is always running.
Here's a sample: I'm creating a Cache item in the global.asax with an expiration. When it expires, an event is fired. You can run your reports or whatever in the OnRemove() event.
Then you can set a call to a page(preferably a very small one) that will trigger code in the Application_BeginRequest that will add back the Cache item with an expiration.
global.asax
private const string VendorNotificationCacheKey = "VendorNotification";
protected void Application_Start(object sender, EventArgs e)
{
//Set value in cache with expiration time
CacheItemRemovedCallback callback = OnRemove;
//Expire after 15 minutes
Context.Cache.Add(VendorNotificationCacheKey, DateTime.Now, null, DateTime.Now.AddMinutes(15), TimeSpan.Zero,
CacheItemPriority.Normal, callback);
}
private void OnRemove(string key, object value, CacheItemRemovedReason reason)
{
SendVendorNotification();
//Need Access to HTTPContext so cache can be re-added, so let's call a page. Application_BeginRequest will re-add the cache.
var siteUrl = ConfigurationManager.AppSettings.Get("SiteUrl");
var client = new WebClient();
client.DownloadData(siteUrl + "default.aspx");
client.Dispose();
}
private void SendVendorNotification()
{
//Do Tasks here
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
//Re-add if it doesn't exist
if (HttpContext.Current.Request.Url.ToString().ToLower().Contains("default.aspx") &&
HttpContext.Current.Cache[VendorNotificationCacheKey] == null)
{
//ReAdd
CacheItemRemovedCallback callback = OnRemove;
Context.Cache.Add(VendorNotificationCacheKey, DateTime.Now, null, DateTime.Now.AddMinutes(15), TimeSpan.Zero,
CacheItemPriority.Normal, callback);
}
}
This works well, if your scheduled task is quick. If it's a long running process..you definitely need to keep it out of your web app.
I haven't had any problems or weird errors thrown with this method.
来源:https://stackoverflow.com/questions/8189655/web-page-as-a-scheduler