7

给定一个 ASP.NET 应用程序,我需要定期(每天、每小时等)运行一个维护过程。

在不依赖外部进程(如服务器上的计划任务)的情况下完成此任务的最佳方法是什么(假设我无权访问服务器 - 共享托管环境)。

4

5 回答 5

12

这是 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));
}

详情:[https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/][1] [1]:https://blog.stackoverflow.com/2008/07/easy -aspnet 中的后台任务/

于 2008-09-05T13:43:38.497 回答
2

如果您不需要在预定时间执行此操作,而只需要“偶尔”进行清理,那么一种方法是在您的 Global.asax Session_OnEnd() 中创建一个函数,该函数将创建一个随机1 到 100 之间的数字,如果数字是 50,则执行维护任务。

当然,您可以减少“100”以使任务更频繁地发生。

在http://www.codeproject.com/aspnet/ASPNETService.asp上还有一篇题为“使用 ASP.NET 模拟 Windows 服务以运行计划作业”的文章,该文章使用过期缓存来模拟计时器。它声称它可以在任何托管站点上运行。

如果您使用的是最后一个,请阅读有关此技术的帖子中的此评论:

您需要非常小心运行任务的长度。每个新任务都是一个新的工作线程,并且数量有限——因为它从托管线程池中“借用”了一个线程。

从框架的 v3.5 开始,最大线程数从 25 个增加到 250 个,增加了 10 倍。但是现在对它们有一个对数启动,因此当它分配更多线程时,它对它们变得更加吝啬。如果您用完托管线程池中的可用线程 - 您的响应时间将超过屋顶。

你真正在这里写的是一个消息/排队系统。

如果您正在做诸如更新缓存之类的事情,那么请务必启动一项新任务。如果您正在执行诸如下载辅助 HTTP 资源或某种密集型数据库工作之类的事情 - 编写一个 Windows 服务并使用一个队列,它可以让您更好地控制每次“咬”多少。

于 2008-09-05T13:40:23.260 回答
2

虽然 Cache 解决方案适用于简单的情况,但如果您的日程安排需要发生变化,您将不走运。相反,您可以使用Quartz.NET,它是流行的 java 框架Quartz的一个端口,它非常灵活。

于 2009-01-24T16:45:06.967 回答
1

虽然 StackOverflow 这样做的方式绝对是独一无二的,但您可能还想监控这个问题,因为它是相关的。

于 2008-09-05T13:57:26.980 回答
0

这是一个外部过程,我不知道有多可靠,但你可以在你知道总是在www.webcron.org上的机器上设置类似的东西。

基本上它所做的就是在您请求的时间表上点击您请求它的页面。

您基本上可以让任何内容定期访问页面,从而启动您的维护任务。

Jeff 和 Joel 在最近的播客中也讨论了通过其他方法做类似的事情。

于 2008-09-05T13:44:50.130 回答