鉴于ASP.NET应用程序,我需要定期运行维护过程(每天,每小时等)。
如果不依赖服务器上的计划任务等外部流程(假设我无法访问服务器 - 共享托管环境),最好的方法是什么。
答案 0 :(得分:11)
以下是StackOverflow的工作方式:
private static CacheItemRemovedCallback OnCacheRemove = null;
protected void Application_Start(object sender, EventArgs e)
{
AddTask("DoStuff", 60);
}
private void AddTask(string name, int seconds)
{
OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
HttpRuntime.Cache.Insert(name, seconds, null,
DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable, OnCacheRemove);
}
public void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)
{
// do stuff here if it matches our taskname, like WebRequest
// re-add our task so it recurs
AddTask(k, Convert.ToInt32(v));
}
详细信息:http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/
答案 1 :(得分:2)
一种方法,如果你不需要在预定的时间内完成它,只需要“偶尔”清理一下,就是在你的Global.asax Session_OnEnd()中创建一个函数,创建1到100之间的随机数,如果数字是50,则执行维护任务。
当然,你可以减少“100”来让任务更频繁地发生。
还有一篇文章标题为“使用ASP.NET模拟Windows服务来运行预定作业”,文章http://www.codeproject.com/aspnet/ASPNETService.asp使用过期缓存来模拟计时器。它声称它可以在任何托管网站上运行。
如果您使用的是最后一个,请从有关此技术的帖子中阅读此评论:
你需要非常小心 任务运行的长度。每一个新的 任务是一个新的工作线程和 这些数量有限 - 如 它“借用”来自托管的线程 线程池。
从Framework的v3.5开始 最大线程数 从25增加到250,增加了10倍。但是 现在有一个对数启动 他们,因为它发出更多的线程 它变得更加狡猾。如果你跑 超出了可用的线程 托管线程池 - 您的响应 时代将会经历 屋顶。
你在这里写的是一个 消息/排队系统。
如果你正在做更新等事情 缓存,然后通过各种方式 - 踢 一项新任务。如果你在做 类似于下载二级的东西 HTTP资源或某种 密集的数据库工作 - 写一个 Windows服务并使用一个队列 让你更多地控制多少 你每次都“咬”。
答案 2 :(得分:2)
虽然Cache解决方案适用于简单的情况,但如果您的日程安排需要改变,那么您将失去运气。相反,您可以使用Quartz.NET,这是一个非常灵活的流行java框架Quartz的端口。
答案 3 :(得分:1)
虽然StackOverflow的做法绝对是独一无二的,但您可能也希望监视此question,因为它与之相关。
答案 4 :(得分:0)
这是一个外部流程,我不知道多么可靠,但你可以在一台你知道永远在www.webcron.org上的机器上设置类似的东西。
它的作用基本上是按照您要求的时间表点击您请求的页面。
你基本上可以在定期的时间表上点击任何内容来启动你的维护任务。
Jeff和Joel还讨论了通过其他方法在最近播客中做类似的事情。