c# - 如何在 C# 中使用 JobStorage 获取所有 Hangfire 作业的列表?

标签 c# asp.net-mvc asp.net-core-2.0 hangfire hangfire-autofac

我正在使用 Hangfire BackgroundJob使用以下代码在 C# 中创建后台作业。

var options = new BackgroundJobServerOptions
        {
            ServerName = "Test Server",
            SchedulePollingInterval = TimeSpan.FromSeconds(30),
            Queues = new[] { "critical", "default", "low" },
            Activator = new AutofacJobActivator(container),
        };
        var jobStorage = new MongoStorage("mongodb://localhost:*****", "TestDB", new MongoStorageOptions()
        {
            QueuePollInterval = TimeSpan.FromSeconds(30)                
        });
        var _Server = new BackgroundJobServer(options, jobStorage);

它创建 Jobserver 对象,然后,我正在创建计划,重复性作业,如下所示。
var InitJob = BackgroundJob.Schedule<TestInitializationJob>(job => job.Execute(), TimeSpan.FromSeconds(5));
        var secondJob = BackgroundJob.ContinueWith<Test_SecondJob>(InitJob, job => job.Execute());
        BackgroundJob.ContinueWith<Third_Job>(secondJob, job => job.Execute());
        RecurringJob.AddOrUpdate<RecurringJobInit>("test-recurring-job", job => job.Execute(), Cron.MinuteInterval(1));

之后,当我的应用程序停止或关闭时,我想删除或停止所有作业。所以在我的应用程序的 OnStop 事件中,我写了下面的代码。
var monitoringApi = JobStorage.Current.GetMonitoringApi();
                    var queues = monitoringApi.Queues();// BUT this is not returning all queues and all jobs
                    foreach (QueueWithTopEnqueuedJobsDto queue in queues)
                    {
                        var jobList  = monitoringApi.EnqueuedJobs(queue.Name, 0, 100);
                        foreach (var item in jobList)
                        {
                            BackgroundJob.Delete(item.Key);
                        }
                    }

但是,上面获取所有作业和所有队列的代码不起作用。它总是返回 "default"排队而不返回所有作业。

任何人都可以使用 Hangfire 获得所有工作的想法JobStorage并在应用程序停止时停止那些工作?

任何帮助将不胜感激!

谢谢

最佳答案

单服务器设置
要获取所有重复性作业,您可以使用作业存储(例如,通过静态实例或 DI):

using (var connection = JobStorage.Current.GetConnection())
{
  var recurringJobs = connection.GetRecurringJobs();
  foreach (var recurringJob in recurringJobs)
  {
    if (NonRemovableJobs.ContainsKey(recurringJob.Id)) continue;
    logger.LogWarning($"Removing job with id [{recurringJob.Id}]");
    jobManager.RemoveIfExists(recurringJob.Id);
  }
}
如果您的应用程序充当单个 Hangfire 服务器,则一旦应用程序停止,所有作业处理都将停止。在这种情况下,它们甚至不需要被移除。
多服务器设置
在为多个服务器使用相同 Hangfire 表的多实例设置中,您会遇到问题,即并非所有应用程序都有可用的所有程序集。使用上述方法 Hangfire 尝试反序列化它找到的每个作业,这会导致“未找到程序集”异常。
为了防止这种情况,我使用了以下解决方法,它从表“Hash”加载列“Key”。它采用“recurring-jobs:{YourJobIdentifier}”格式。然后,如果需要,作业 ID 用于删除作业:
var queue = 'MyInstanceQueue'; // probably using queues in a multi server setup
var recurringJobsRaw = await dbContext.HangfireHashes.FromSqlInterpolated($"SELECT [Key] FROM [Hangfire].[Hash] where Field='Queue' AND Value='{queue}'").ToListAsync();
var recJobIds = recurringJobsRaw.Select(s => s.Key.Split(":").Last());
foreach (var id in recJobIds)
{
  if (NonRemovableJobs.ContainsKey(id)) continue;
  logger.LogWarning($"Removing job with id [{id}]");
  jobManager.RemoveIfExists(id);
}
P.S.:为了让它与 EF Core 一起工作,我使用了 Keyless entity对于 Hangfire.Hash 表。

关于c# - 如何在 C# 中使用 JobStorage 获取所有 Hangfire 作业的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54141581/

相关文章:

c# - 无法将 void 转换为 ICommand

asp.net-mvc - 使用带有 Ajax 请求的部分 View 构建表

c# - ASP .NET Core 2.0 中的自记录 REST 服务

c# - 没有注册类型 'MyType' 的服务

c# - 数字范围和字符的正则表达式

C# SmtpClient发送失败: An invalid argument was supplied

c# - 使用 AngularJS 从 ASP.NET Web API 方法下载文件

asp.net-mvc - 使用 Automapper 返回 IQueryable

jquery - 是否可以通过单个 ajax 调用一次填充 2 个 jqGrid?

asp.net-core - 如何统计 ASP.NET Core 2.0 中具有特定角色的所有用户