如何在Hangfire工作成功或失败的情况下执行新工作?

时间:2015-11-14 00:07:46

标签: asp.net-web-api2 autofac hangfire

我正在处理一个Web API RESTful服务,该服务在请求中需要执行任务。我们使用Hangfire将该任务作为一项工作执行,如果失败,将尝试重试该作业最多10次。

如果作业最终成功,我想运行一个额外的工作(将事件发送到另一个服务)。如果即使在所有重试尝试之后作业仍然失败,我想运行另一个额外的作业(将失败事件发送到另一个服务)。

然而,我无法弄清楚如何做到这一点。我创建了以下JobFilterAttribute:

public class HandleEventsAttribute : JobFilterAttribute, IElectStateFilter
{
    public IBackgroundJobClient BackgroundJobClient { get; set; }

    public void OnStateElection(ElectStateContext context)
    {
        var failedState = context.CandidateState as FailedState;
        if (failedState != null)
        {
            BackgroundJobClient.Enqueue<MyJobClass>(x => x.RunJob());
        }
    }
}

我遇到的一个问题是将IBackgroundJobClient注入此属性。我不能将它作为属性传递给属性(我得到一个“无法在静态上下文中访问非静态字段'backgroundJobClient'”错误)。我们使用autofac进行依赖注入,我试图弄清楚如何使用属性注入,但我很茫然。所有这些让我相信我可能走错了路。

如果Hangfire作业失败,我认为运行一些额外的清理代码是一种相当常见的模式。大多数人如何做到这一点?

感谢您的帮助。如果我能提供任何其他详细信息,请告诉我。

2 个答案:

答案 0 :(得分:1)

Hangfire可以构建执行链。如果您想在第一个作业成功后安排下一个作业,则需要ContinueWith(string parentId, Expression<Action> methodCall, JobContinuationOptions options);使用JobContinuationOptions.OnlyOnSucceededState才能在成功后运行它。

但您可以像JobExecutor一样创建一个HangFire扩展,并在其中运行任务以获得更多可能性。

类似的东西:

public static JobResult<T> Enqueue<T>(Expression<Action> a, string name)
{
    var exprInfo = GetExpressionInfo(a);

    Guid jGuid = Guid.NewGuid();

    var jobId = BackgroundJob.Enqueue(() => JobExecutor.Execute(jGuid, exprInfo.Method.DeclaringType.AssemblyQualifiedName, exprInfo.Method.Name, exprInfo.Parameters, exprInfo.ParameterTypes));            

    JobResult<T> result = new JobResult<T>(jobId, name, jGuid,  0, default(T));
    JobRepository.WriteJobState(new JobResult<T>(jobId, name, jGuid, 0, default(T)));

    return result;
}

您可以在此处找到更详细的信息:https://indexoutofrange.com/Don%27t-do-it-now!-Part-5.-Hangfire-job-continuation,-ContinueWith/

答案 1 :(得分:0)

我还没有能够验证这是否有效,但是BackgroundJobClient没有静态方法,所以你需要引用它的实例。

当我将任务排入队列时,我使用静态Hangfire.BackgroundJob.Enqueue,它应该在不引用JobClient实例的情况下工作。

史蒂夫