如何在 asp.net MVC 中创建定时调度程序?

Posted

技术标签:

【中文标题】如何在 asp.net MVC 中创建定时调度程序?【英文标题】:How do I create a timed scheduler in asp.net MVC? 【发布时间】:2019-07-06 15:54:35 【问题描述】:

我想在一个MVC网站中为应用功能创建一个比较简单的定时事件调度功能,目前不一定针对用户,但将来可能会。我目前的愿望是使用时间表根据定时事件对网站进行特定更改。大致思路如下文末。

我首先研究了用于 asp.net 的 Quartz,因为它在其他帖子中被推荐,但该开源包中的建议特别建议不要在嵌入式模式下使用它。我认为我不能将它作为服务添加到托管 MVC 站点的服务器。

虽然我熟悉多线程的概念,但我对它没有经验。在后台线程上运行下面的 Timer Process 是一个很好的解决方案,还是我应该看其他东西?我假设 Timer Process 将永远执行,将计划与系统时钟进行比较,并在时间触发发生时运行所需的事件代码。

如果线程是一个坏主意,请告诉我应该去哪里看。如果线程是正确的想法,任何建议或警告将不胜感激。我现在正在阅读线程。

我有几个具体问题:

1) Should the individual event code run on the same thread, or does it matter? 
2) How do I handle the problem others have suggested occurs if 'IIS kills the thread' or the 'app pool is recycled'.
3) Is it a wrong idea that I send some message to the MVC site that triggers the Timer Process to overcome the issues in #2 above?
4) Is there a way to force a page to automatically refresh with a new display when the timer event occurs?  That doesn't seem to be the way asp.net MVC normally works.

最后,这听起来像是其他人可能已经解决并简化为 asp.net MVC 的开源解决方案的问题。当我浏览 Nu-Get 时,有一些似乎描述了这个问题,但它们的下载量很少。这条路线有什么建议吗?

【问题讨论】:

对于 Asp.NET Core,请查看 IHostedService。 恕我直言,一些cron 作业甚至是单独 Windows 调度程序作业 - 本质上,在/从 Web 应用程序外部/分离,用于你已经研究过的原因。不确定您所说的“配置更改”是什么意思——通常这些更改会触发应用重启。 @EdSF 我假设您指的是“使用新配置刷新”-我的措辞选择不当-我会纠正它。想问一下如何强制刷新页面。例如,根据一天中的时间更改显示的图片。我试图了解如果页面上的某些工件应该在给定时间更改,如何强制页面重新显示,这是我了解如何获得可靠的计时器事件后我必须完成的下一个任务发生。感谢您提出在 MVC 应用程序之外完成计时的建议。 @Alan - “页面刷新”是一些客户端/最终用户的事件。定时过程(没有用户)有什么价值?如果您说“重置”/“无效”某些缓存资源(图像),那么也许这就是您应该寻找的地方(?)。如果只是基于某种逻辑评估的动态显示,那听起来也不需要额外的“工作”吗? @Alan 那么所有这些都是客户端(javascript)-您希望在客户端触发(轮询)。您也可以查看SignalR 【参考方案1】:

我认为在你的情况下使用 Hangfire 会很好。您可以像并行服务器一样配置并创建具有不同时间表的不同作业。

对于 NetCore 应用程序:

app.UseHangfireServer();
app.UseHangfireDashboard("/hangfire", options);

// Process notifications every 6 hours
RecurringJob.AddOrUpdate<B2CEngineNotifications>(jobEngine =>  jobEngine.SendBillingNotifications(), "0 */6 * * *");

在这种情况下,每个作业都在自己的线程中工作。

1) 单个事件代码是否应该在同一个线程上运行,或者是否重要? 这取决于您期望的事件类型。如果它们不依赖,您可以在单独的线程中执行此操作。

如果出现“IIS 终止线程”或“应用程序池被回收”,我该如何处理其他人建议的问题。 Hangfire 将在您的数据库中创建一些表。如果您将终止进程,则在下次启动时,它会从 db 中获取所有数据并在 sedule 上开始执行事件。

我向 MVC 站点发送一些消息以触发计时器进程以克服上述 #2 中的问题,这是一个错误的想法吗? Hangfire 有自己的界面来管理作业。或者您需要选择从 MVC 应用程序启动事件?您可以从 MVC 中执行此操作,只需更改 db 值。 hangfire 将开始工作。

有没有办法在定时器事件发生时强制页面自动刷新并显示新的显示?这似乎不是 asp.net MVC 通常的工作方式。 在这种情况下,您需要使用 AJAX 与服务器建立“实时”连接,并且“询问”是否发生了变化。

【讨论】:

我听从了你的建议尝试了hangfire,谢谢。我已经成功启动并运行它,但只是根据简单的教程。我所做的只是记录消息。我现在想了解我如何继续执行可操作的代码。无论是批处理文件,我都不会很快使用它,还是重新进入 MVC 代码。从我读过的内容来看,这对我来说并不明显。我可能不得不再发一个 SO 帖子来询问这个问题,但我想我会先在这些 cmets 中问你,如果你有一个可能有帮助的链接。 嗨@Alan。如果我理解正确,您在 MVC 中有一些您想开始的课程。您可以创建新类public class B2CEngineNotifications : IEngine public void DoSomething() //call your class which you injected in constructor 或者您能否详细描述一下“要执行的可操作代码” 在我发布之后,通常情况下,经过反思,我想到 GitHub 上的示例 hangfire MVC 项目中发生了什么,我能够安排工作。我在 Startup.vb 中添加了以下行:RecurringJob.AddOrUpdate(Sub() HomeController.Event1(), Cron.Minutely)。我花了一段时间才获得将 C# 翻译成 VB.net 的帮助。非常感谢您的帮助。下一期……

以上是关于如何在 asp.net MVC 中创建定时调度程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 asp.net mvc 中创建审计日志/审计跟踪

如何在 ASP .net MVC 4 应用程序的 HTML5 中创建带有可点击选项的水平条形图? [关闭]

ASP.NET MVC 调度器开源? [关闭]

ASP.NET MVC 和 ASP.NET 成员资格模板提供程序

如何在现有数据库中创建 ASP.Net Identity 表?

如何在 ASP.NET MVC 中创建 CheckBoxListFor 扩展方法?