在托管 Web 服务器中安排作业

Posted

技术标签:

【中文标题】在托管 Web 服务器中安排作业【英文标题】:Schedule a job in hosted web server 【发布时间】:2010-11-11 04:49:04 【问题描述】:

谁能给我一个使用 .NET 技术实现日常工作的最佳方法。 我有一个 sqlserver 数据库托管在共享主机中的 asp.net 应用程序,在我的实例中是 GODaddy。 我的应用程序用于添加/更改数据库中的数据,该数据库目前表现相当不错。 我有一个新要求,即每天根据存储在数据库中的一些数据标准发送一些电子邮件警报。

最初我想写一个 Windows 服务,但 godaddy 不允许访问除托管应用程序以外的数据库。 有人知道每天凌晨 1:00 发送警报吗?

提前致谢

【问题讨论】:

【参考方案1】:

请参阅 Jeff Atwood 的 Easy Background Tasks in ASP.NET。

从链接复制/粘贴:

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));

【讨论】:

感谢您的回复。使用上面的代码而不是 protected void Application_Start(object sender, EventArgs e) Thread invAlertThread = new Thread(newThreadStart(Alerts.SendAlerts)); 是否有任何性能提升? invAlertThread.Name = "发票提醒"; invAlertThread.Start(); 其中 Alerts.SendAlerts 是一个静态方法 public class Alerts public static SendAlerts() // 在此处发送警报 // 5 小时 Thread.Sleep(18000000);发送警报(); @krishna 我不认为从 Application_Start 开始新线程是个好主意。 谁能确认这在 GoDaddy windows 共享主机环境中实际工作?【参考方案2】:

除了域名注册之外,我没有使用 GoDaddy 进行任何其他操作,因此对于您在他们的托管平台上可以做什么或不可以做什么,我没有任何经验。我也不知道他们的支持或知识库是什么样的,但我想说你最好的选择是询问 GoDaddy 他们的建议。否则,您可能会继续实施技术上可行但被托管公司阻止的东西。

如果它不是黄金时段的应用程序,那么一种快速而肮脏的事情就是让某种外部机器人调用服务器上的(安全)网页来触发通知过程。不是一个真正的解决方案,但如果这个网站只是你的爱好,它可以让你通过,直到你找到主机允许的东西。

如果新主机不符合您的要求,这也是寻找新主机的好时机。现在有很多优秀的 ASP.NET 主机可用。

【讨论】:

【参考方案3】:

您可以使用来自 Web 服务器的 Windows 调度程序来调度可以根据特定条件发送邮件的存储过程调用。

osql.exe -S servername -d database -U username -P password -Q "EXEC spAlertOnCriteria"

参考资料:

osql Task Scheduler

【讨论】:

【参考方案4】:

许多托管服务提供商可以每 X 分钟为您请求一个 URL。我不知道 GoDaddy 是否这样做,但如果是这样,您可以创建一个启动工作的 ASMX 页面,并告诉他们自动执行它。

如果他们不这样做,一种解决方案可能是在每次页面请求时在后台线程中启动作业。如果您这样做,请确保您输入的代码将其限制为每 X 分钟或更长时间运行一次(可能使用静态变量或数据库表)-阅读this story

【讨论】:

【参考方案5】:

如果您可以在托管应用程序和数据库的网站上公开一项服务(当然是经过身份验证的服务),那么您可以从任何带有凭据的盒子远程访问该服务,提取数据,然后以这种方式发送邮件.

这可能是编写为 Windows 服务的自动化流程、在调度程序下运行的应用程序,或者您在凌晨 1:00 按下的某个按钮。你的选择。

仅仅因为应用程序是唯一可以访问数据库的东西并不意味着您不能以其他方式公开数据。

【讨论】:

【参考方案6】:

使用 System.Timers、System.Threading 来创建在预定时间运行的实例。让该线程执行您想要的任何任务...确保代码是线程安全的!

【讨论】:

什么保证 appdomain 在凌晨 1:00 运行?不会因为没有活动而被卸载吗? 为什么线程会被卸载?它在启动时初始化并在后台运行,直到检查是否有任何任务要执行?如果你不明白..那么我很抱歉缺乏细节如果你注意到了,我提出的建议基本上是他已经实施的

以上是关于在托管 Web 服务器中安排作业的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Developer 中安排作业

如何在 pl/sql 中安排作业?

如何在 Big Query 中安排每日插入作业 [重复]

我如何在Gitlab中安排不同时间的作业

没有在Google App Engine中安排的Cron作业

如何在 celery 中安排工作日感知工作