(注意!这是 OP 问题的解决方案。它不回答“如何获取当前尝试次数”的问题。如果这是您想要的,请参阅 accepted answer 例如)
使用作业过滤器和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 应用于它。不要全局注册它,或者给它添加一些额外的逻辑......