面向ASP.NET核心的动态任务调度器


ASP.NET有许多任务计划程序。其中两个比较著名的是Quartz.NETHangfire。这两个工具都很棒,我自己也曾亲自使用过Hangfire并取得了很大的成功。但是,它们在使用上都缺乏灵活性和/或复杂性。

Quartz.NET的API过于复杂,基于配置文件,格式难以理解,在声明任务时没有语法高亮显示或自动完成功能。此外,实际创建一个简单任务所需的代码量有时感觉大得惊人,而且不必要地复杂。事实是“已移植”from Java显示了您试图学习它的API。

因此,即使它是一个令人惊讶的高质量的作品,它仍然没有达到任何库和组件都应该具有的最重要的特性:简单性!

另一方面,Hangfire由持久数据库和仪表板支持,允许您在GUI中管理任务,并将它们存储在数据库中。但是,它的主要优势也成为它的主要劣势。有时候,你想要的只是一个简单的组件,你可以通过NuGet拉入,调用一些方法,并为你自动创建一些后台任务--你可以相信,一旦它们的日期到期,它们就会被执行。

你可能还喜欢:Customizing ASP.NET Core Part 10: TagHelpers

老实说,挂火简直太过分了。事实上,Quartz.NET和Hangfire在许多方面是完全相反的,因此需要一些“中间地带”这里。所以,我创造了魔法调度器。

魔术调度程序

上图说明了如何创建一个应该在每周三22:30重复的任务。当然,上面的任务只是创建一个日志条目,其内容为“今天是星期三,”但是在上图中你不容易看到的是这个任务调度器的DSL容量。

上图中的大黑框接受Hyperlambda,它是一个。NET DSL,允许您轻松地绑定到现有的C#代码中,让一些C#代码片段按照某种模式执行。以以下C#代码为例:

using magic.node;
using magic.node.extensions;
using magic.signals.contracts;

namespace acme
{
    [Slot(Name = "create-database-backup")]
    public class CreateDatabaseBackup : ISlot
    {
        public void Signal(ISignaler signaler, Node input)
        {
            var databaseName = input.GetEx<string>();

            /*
             * Create backup of specified database here ...
             */
        }
    }
}


请注意上面的属性,它的名称为“创建-数据库-备份。”然后看看下面的截图,Magic是如何自动给你自动完成与上面的槽作为它的建议之一。

Magic的自动完成功能

是的,无论你在自己的代码中声明什么ISlot类,Magic的前端会自动给你自动完成,通过你的浏览器在你的后端仪表板。此外,您还可以很容易地将参数传递给您的插槽,您可以从您的C#代码中引用这些参数。当然,这是一个主要的优势,而不是来自的晦涩难懂的配置格式Quartz.NET,特别是对于那些只想创建某种背景任务并让它每隔一个月执行一次的新用户来说。

此外,任务是在运行时创建的,无需中断正常使用,允许您在生产中添加,创建,删除和修改任务。无需编译C#代码和重新启动Web应用程序。(为记录起见,单击Ctrl+Space在Magic的Hyperlambda编辑器中触发AutoCompleter.)

当您声明了您的任务的Hyperlambda后,您可以立即测试它,它将在您的主HTTP请求线程上执行它,允许您单步执行您的C#代码。这允许您验证您的任务是否实际工作,然后将它留给您的调度程序,例如在下周三执行它--此时它可能工作,也可能不工作。请看下面的屏幕截图,并注意其“跑”按钮。下面是在最初为记录创建任务之后,当您查看该任务时的样子。

正在创建数据库备份

然后,您需要一些方法来筛选和搜索您的任务,轻松地向您显示所有即将到来的任务。这就是魔术里的样子。

筛选任务

请注意,如果由于某种原因,您不再希望任何任务继续执行,您也可以如何停止调度程序。但最后一点,对我来说,它最棒的一点是,您用来声明任务内容的DSL语言也可以很容易地用来声明整个任务。是的,甚至声明任务本身也可以使用Hyperlambda完成。这允许您分发,例如,您的魔术安装,使它“开箱即用”创建一组默认任务。

这允许您分发Hyperlambda管道中在启动期间执行的文件,创建“默认任务”它们将按照某种重复模式执行。下面是一个Hyperlambda的片段,向您展示了如何做到这一点。

scheduler.tasks.create:some-tuesday-task
   description:This task will execute every tuesday at 10PM
   repeat:Tuesday
      time:"22:00"
   .lambda
      log.info:It is Tuesday today!


很酷,嗯。。。?

我也这么想。Get the goods over here

obtain a proprietary license here


进一步阅读