我知道这个简单代码每隔午夜执行一个方法,我有一个共享主机(不可能创建一个Windows计划),但这不起作用。有什么想法吗?
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.DefaultNamespaces.Add("PhotoPremier.Controllers");
var dt = NextAt(new TimeSpan(0, 0, 0)); //
var timer = new Timer(new TimerCallback(callback), HttpContext.Current, dt - DateTime.Now, TimeSpan.FromHours(24));
}
static void callback(Object stateObject)
{
DbLayer.ContestManager cm = new DbLayer.ContestManager();
cm.UpdateAllPhotosInContest();
}
DateTime NextAt(TimeSpan time)
{
DateTime now = DateTime.Now;
DateTime result = now.Date + time;
return (now <= result) ? result : result.AddDays(1);
}
答案 0 :(得分:1)
这可能是由于共享主机中的IIS设置。
默认情况下,IIS配置会在一定时间后关闭应用程序,而无需任何人访问它。 IIS也会每隔几分钟回收一次应用程序池。
除非您能够控制此设置,否则您将很难保持应用程序处于活动状态并触发计时器的触发器。
为了澄清这种情况并建议其他替代方案,我给你以下链接:
答案 1 :(得分:0)
我认为Unique解决方案是使用Quarts.Net Framework。
非常简单,在这里有一个简单的代码。
public class DailyJob : IJob
{
public DailyJob() { }
public void Execute( JobExecutionContext context )
{
try {
DbLayer.ContestManager cm = new DbLayer.ContestManager();
cm.UpdateAllPhotosInContest();
} catch( Exception e ) {
//Handle this please
}
}
public static void ScheduleJob( IScheduler sc )
{
JobDetail job = new JobDetail("FinishContest", "Daily", typeof(DailyJob));
sc.ScheduleJob(job, TriggerUtils.MakeDailyTrigger("trigger1", 0, 0));
sc.Start();
}
}
//Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
/* HERE */ DailyJob.ScheduleJob(new StdSchedulerFactory().GetScheduler());
}
答案 2 :(得分:0)
当我最近尝试做同样的事情时,我发现我的问题是在某个地方声明我的Timer对象,它会收集垃圾。如果您使计时器成为您的类的成员而不是在Application_Start中本地声明它,我认为原始海报的代码将起作用。
希望这有助于某人。