簡體   English   中英

如何在 C# 中使用 JobStorage 獲取所有 Hangfire 作業的列表?

[英]How to get List of all Hangfire Jobs using JobStorage in C#?

我正在使用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);
}

PS:為了讓它與 EF Core 一起工作,我為 Hangfire.Hash 表使用了一個Keyless 實體

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM