当前位置:  开发笔记 > 编程语言 > 正文

运行计划任务的最佳方式

如何解决《运行计划任务的最佳方式》经验,为你挑选了6个好方法。

今天我们构建了一个控制台应用程序,用于运行ASP.NET网站的计划任务.但我认为这种方法有点容易出错且难以维护.如何执行计划任务(在Windows/IIS/ASP.NET环境中)

更新:

任务示例:

从数据库中的电子邮件队列发送电子邮件

从数据库中删除过时的对象

从Google AdWords检索统计信息并填写数据库中的表格.

BC... 128

Jeff Atwood为Stackoverflow提供的这种技术是我遇到过的最简单的方法.它依赖于构建到ASP.NET缓存系统中的"缓存项目已删除"回调机制

更新:Stackoverflow已经超出了这个方法.它只在网站运行时有效,但它是一种非常简单的技术,对很多人都有用.

另请参阅Quartz.NET



1> BC...:

Jeff Atwood为Stackoverflow提供的这种技术是我遇到过的最简单的方法.它依赖于构建到ASP.NET缓存系统中的"缓存项目已删除"回调机制

更新:Stackoverflow已经超出了这个方法.它只在网站运行时有效,但它是一种非常简单的技术,对很多人都有用.

另请参阅Quartz.NET


我在今天对原始博客文章的评论中注意到了一些事情:"不,我们已经切换到专门的任务.我们肯定超过了这种技术.我认为这对小型网站来说很好!` - 杰夫阿特伍德
那么如果应用程序没有运行会发生什么,但是计划任务需要发生?
这太可怕了!任何事情都可能导致应用程序停止运行,它可能只会在下一个用户请求时重新启动.在这些时间之间,你的任务不会运行!
-1这种方法存在很大的缺陷.每当应用程序被回收时,"CacheItemRemoved"事件将触发,并且您的计划任务将运行.在生产现场,这可能每天发生几次.如果您希望每周运行任务,那就不太好了.
如果任务恰好需要一段时间才能运行,这也可能会减慢用户体验.我不希望让用户为我生成维护/任务.

2> Brettski..:

我的所有网站任务(需要安排)都保存在网站内,并从特殊页面调用.然后我写了一个简单的Windows服务,每隔一段时间调用一次这个页面.页面运行后,它返回一个值.如果我知道还有更多的工作要做,我会马上再次运行页面,否则我会在一段时间内运行它.这对我来说非常有效,并且我的所有任务逻辑都与Web代码保持一致.在编写简单的Windows服务之前,我使用Windows调度程序每x分钟调用一次页面.

另一种方便的方法是使用Pingdom等监控服务.将他们的http检查指向运行您的服务代码的页面.让页面返回结果,然后可以用来触发Pingdom在出现问题时发送警报消息.


您是否查看了缓存项目到期技术?我想你会发现它是一个更理想的预定服务实现:http://www.codeproject.com/KB/aspnet/ASPNETService.aspx
什么阻止恶意用户(或搜索引擎蜘蛛)调用此页面,从而导致您的计划任务运行?
您可以通过在Web应用程序中存储静态时间戳来阻止恶意呼叫,并且仅在尚未设置时间戳(第一次呼叫)或自上次呼叫后正确时间已到期时运行.
我通过检查IP地址是否是内部地址来阻止对我的URL的恶意调用.如果它不属于我们组织的内部,它什么也不返回,什么都不做.
这是我最终解决的问题.我使用Windows scheduler + curl而不是自定义Web服务.使用Windows服务有什么好处.
没有任何好处,这就是你把它放在一起的方式.你的是一个很好的解决方案.

3> Chris Van Op..:

创建自定义Windows服务.

我将一些任务关键任务设置为计划的控制台应用程序,并发现它们很难维护.我创建了一个带有'heartbeat'的Windows服务,可以每隔几分钟检查一次我的数据库中的计划.它运作得很好.

话虽如此,我仍然使用预定的控制台应用程序来执行大多数非关键维护任务.如果没有损坏,请不要修理它.


仅供参考,链接现已死亡.

4> Daniel Auger..:

我发现所有参与者都很容易:

创建Web服务方法,例如DoSuchAndSuchProcess

创建一个调用此web方法的控制台应用程序.

在任务计划程序中安排控制台应用程序.

使用此方法,所有业务逻辑都包含在您的Web应用程序中,但您具有Windows任务管理器或任何其他商业任务管理器的可靠性,可以将其启动并记录任何返回信息(如执行报告).使用Web服务而不是发布到页面有一些优势,因为它更容易从Web服务返回数据.



5> 小智..:

为什么重新发明轮子,使用线程和Timer类.

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }


@IdanShechter告诉你为什么认为这不是一个理想的解决方案会很好
你不需要生成一个线程来启动一个计时器......
我也认为这不是一个理想的解决方案.
线程可能有问题,因为它不是HttpRequest,一些涉及HttpRequest的数据可以为null.例如HttpRequest .ApplicationPath.如果任务写得正确,它将起作用.另一个问题是应用程序池重新启动.如果池太频繁重启(内存泄漏......),工作人员将永远不会运行.
如果你有几个实例运行(例如负载平衡) - 可能你不会想要这个解决方案(几个任务做同样的事情)

6> 小智..:

使用Windows Scheduler运行网页.

为防止恶意用户或搜索引擎蜘蛛运行它,在设置计划任务时,只需使用查询字符串调用网页,即:mypage.aspx?from = scheduledtask

然后在页面加载中,只需使用一个条件:if(Request.Querystring ["from"] =="scheduledtask"){// executetask}

这样,搜索引擎蜘蛛或恶意用户就无法执行您的计划任务.


更安全的是,使用Windows Scheduler运行一个网页,检查请求是否来自服务器本身:`Request.IsLocal` >>只有服务器本身可以运行计划任务,没有其他人.
更好的是,使用salted哈希算法实际验证查询字符串的安全性比魔术短语更高.req会像mypage.aspx?salt = foo&hash = 1223523jbhdgu13t1.您只需要在服务器和客户端上使用相同的哈希算法.还要在服务器上添加硬限制; 执行时保存,防止执行过快.我可能是偏执狂.
推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有