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

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

有帮助吗?

解决方案

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/

其他提示

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

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

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

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

您需要在任务的长度上非常小心。每个新任务都是一个新的工作人员线程,其中数量有限 - 因为它从托管线程池“借用”了一个线程。

从框架的v3.5开始,最大螺纹数量从25增加到250。但是现在,他们有一个对数初创公司,因此随着更多的线程与它们变得更加刺痛。如果您在托管线程池中用完了可用的线程,那么您的响应时间将通过屋顶。

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

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

虽然缓存解决方案适用于简单的情况,但如果您的调度需求发生变化,您就会不走运。相反,你可以使用 石英网, ,流行的java框架的端口 石英, ,这是非常灵活的。

虽然 StackOverflow 执行此操作的方式绝对是独一无二的,但您可能需要监视它 问题 也,因为它涉及。

这是一个外部进程,我不知道有多可靠,但您可以在您知道始终处于开启状态的机器上设置类似的内容 www.webcron.org.

基本上它的作用是按照您请求的时间表点击您请求的页面。

本质上,您可以让任何内容定期出现在页面上,从而启动您的维护任务。

杰夫和乔尔还在最近的播客中讨论了通过其他方法做类似的事情。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top