Asp.net-Mvc

如何在 Hangfire 中獲取後台作業的目前嘗試次數?

  • July 12, 2021

在我的 Hangfire 後台作業的最後一次嘗試結束之前,我需要執行一些數據庫操作(我需要刪除與作業相關的數據庫記錄)

我目前的工作設置了以下屬性:

[AutomaticRetry(Attempts = 5, OnAttemptsExceeded = AttemptsExceededAction.Delete)]

考慮到這一點,我需要確定目前的嘗試次數是多少,但我很難從 Google 搜尋或 Hangfire.io 文件中找到這方面的任何文件。

只需添加PerformContext到您的工作方法中;您還可以JobId從此對象訪問您的。對於嘗試次數,這仍然依賴於魔術字元串,但它比目前/唯一的答案要少一點:

public void SendEmail(PerformContext context, string emailAddress)
{
   string jobId = context.BackgroundJob.Id;
   int retryCount = context.GetJobParameter<int>("RetryCount");
   // send an email
}

(注意!這是 OP 問題的解決方案。它不回答“如何獲取目前嘗試次數”的問題。如果這是您想要的,請參見例如接受的答案

使用作業過濾器和OnStateApplied回調:

public class CleanupAfterFailureFilter : JobFilterAttribute, IServerFilter, IApplyStateFilter
{
   public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
   {
       try
       {
           var failedState = context.NewState as FailedState;
           if (failedState != null)
           {
               // Job has finally failed (retry attempts exceeded)
               // *** DO YOUR CLEANUP HERE ***
           }
       }
       catch (Exception)
       {
           // Unhandled exceptions can cause an endless loop.
           // Therefore, catch and ignore them all.
           // See notes below.
       }
   }

   public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
   {
       // Must be implemented, but can be empty.
   }
}

將過濾器直接添加到工作職能中:

[CleanupAfterFailureFilter]
public static void MyJob()

或全域添加:

GlobalJobFilters.Filters.Add(new CleanupAfterFailureFilter ());

或像這樣:

var options = new BackgroundJobServerOptions
{   
   FilterProvider = new JobFilterCollection { new CleanupAfterFailureFilter () };
};

app.UseHangfireServer(options, storage);

或查看http://docs.hangfire.io/en/latest/extensibility/using-job-filters.html了解有關作業過濾器的更多資訊。

注意:這是基於接受的答案:https ://stackoverflow.com/a/38387512/2279059

不同之處在於OnStateApplied使用 代替OnStateElection,因此僅在最大重試次數後才呼叫過濾器回調。這種方法的一個缺點是不能中斷到“失敗”的狀態轉換,但在這種情況下不需要這樣做,並且在大多數情況下,您只想在作業失敗後進行一些清理。

注意:空catch處理程序不好,因為它們可以隱藏錯誤並使它們難以在生產中調試。這裡是必要的,所以回調不會永遠被重複呼叫。您可能希望記錄異常以進行調試。還建議降低作業過濾器中出現異常的風險。一種可能性是,而不是就地進行清理工作,而是安排一個新的後台作業,如果原始作業失敗,該作業將執行。但請注意不要將過濾器CleanupAfterFailureFilter應用於它。不要全域註冊它,或者向它添加一些額外的邏輯……

引用自:https://stackoverflow.com/questions/38368153