【问题标题】:How do I execute a new job on success or failure of Hangfire job?如何在 Hangfire 作业成功或失败时执行新作业?
【发布时间】:2015-11-14 00:07:45
【问题描述】:

我正在开发一个 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 作业失败,运行一些额外的清理代码将是一种相当常见的模式。大多数人是怎么做到的?

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

【问题讨论】:

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


    【解决方案1】:

    Hangfire 可以构建一个执行链。如果您想在第一个作业成功后安排下一个作业,则需要使用ContinueWith(string parentId, Expression&lt;Action&gt; 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/

    【讨论】:

      【解决方案2】:

      我无法验证这是否可行,但 BackgroundJobClient 没有静态方法,因此您需要对其实例的引用。

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

      史蒂夫

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-16
        • 1970-01-01
        相关资源
        最近更新 更多