Hangfire能否在不重新部署的情况下处理定时任务的变化

Can Hangfire Handle Changes to Scheduled Tasks Without Redeployment

我一直在 Microsoft MVC 应用程序中使用 Hangfire。我已经得到它来编译和安排即发即弃的任务,但令我惊讶的是当程序是 运行 时我不能 add/remove 作业。 Hangfire 真的不能在运行时动态调度任务吗?有没有一个著名的框架,即使在应用程序已经编译或部署后,也可以安排任务,而无需每次我想添加任务时更改 C# 代码?

我也研究了Quartz.NET,好像也有同样的问题

编辑:

Windows Task Scheduler 可以允许使用 GUI 安排任务,UNIX 的 cron 可以通过编辑文件来添加或删除任务,但我正在寻找某种应用程序 运行 在 Windows 上允许用户在 部署应用程序后 添加或删除任务。我不想每次添加或删除任务时都重新编译应用程序。

正如所问,问题似乎在于对 "dynamic...during runtime" 含义的误解。答案是 "yes," 它可以在不重新部署的情况下更改任务(但这似乎不是您真正想要的)。

Hangfire 会在您的应用程序中添加一个仪表板 UI 如果您将其配置为这样做,但它本身并不是一个端到端的任务管理应用程序。它旨在为您的应用程序提供安排工作的能力,并使该工作从调用点开始以非常不连贯的方式完成——它甚至可能无法在同一台机器上完成.

它仅限于调用 .NET 代码,但是根据定义这满足了您对"dynamically schedule tasks during runtime."提出的要求这可以响应应用程序中的任何事件来完成你喜欢。也可以删除、更新和取消任务。

(Post-edit) 你是对的:任何调度 UI 或任务文件格式的反序列化你必须自己写.如果您正在寻找可以为您提供 UI and/or 任务文件 OOTB 的工具,您可能需要升级到像 JAMS 这样的商业产品。 (免责声明:这甚至可能本身不具备您需要的功能——我没有使用该产品的直接经验,但与我共事过的人都以积极的态度提到过它)。

创建一个 API 以在 运行 时间后动态安排作业。您的 API 可以通过 HTTP Get/Put/Post/Delete 等接受输入,然后在 API 调用时使用您提供的数据 运行 您的代码中任何内容的实例。

例如,假设您的代码中有一个硬编码的任务 A 和任务 B,并且您希望使用不同的参数动态地安排它们 运行。您可以创建一个 API,它将 运行 使用您选择的参数在指定时间完成所需的任务。

[HttpPost]
public IHttpActionResult Post([FromBody]TaskDto task)
{
    var job = "";
    if(task.TaskName == "TaskA"){
        job = BackgroundJob.Schedule(() => RunTaskA(task.p1,task.p2), task.StartTime);
    }
    if(task.TaskName == "TaskB"){
        job = BackgroundJob.Schedule(() => RunTaskB(task.p1,task.p2), task.StartTime);
    }

    if(!string.IsNullOrWhiteSpace(task.ContinueWith) && !string.IsNullOrWhiteSpace(job)){       
        if(task.ContinueWith == "TaskB"){
            BackgroundJob.ContinueWith(job, () => RunTaskB(task.p3,task.p4));
        }
        if(task.ContinueWith == "TaskA"){
            BackgroundJob.ContinueWith(job, () => RunTaskA(task.p3,task.p4));
        }
    }
    return Ok(job)
}

然后您可以使用 JSON POST 调用 API(使用 javascript 的示例)

// Sending JSON data to start scheduled task via POST
//
var xhr = new XMLHttpRequest();
var url = "https://www.example.com/api/scheduletask";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var json = JSON.parse(xhr.responseText);
    }
};
var data = JSON.stringify({"TaskName": "TaskA", "ContinueWith": "TaskB",
"StartTime": "2-26-2018 10:00 PM", "p1": "myParam1", "p2": true, 
"p3": "myParam3", "p4": false});
xhr.send(data);

为了示例的完整性,这里是此示例的 TaskDto class

public class TaskDto
{

    public string TaskName { get; set; }
    public string ContinueWith { get; set; }
    public DateTime StartTime { get; set; }
    public string p1 { get; set; }
    public bool p2 { get; set; }
    public string p3 { get; set; }
    public bool p4 { get; set; }

}