首页 > 解决方案 > 在应用程序启动时设置 Hangfire 循环作业时出错

问题描述

我正在尝试在应用程序启动时(在 .NET.Core Web 应用程序中)设置 Hangfire 循环作业Startup.cs,以便我们可以确保它们始终被注册。我设法让它为一个虚拟工作工作,但我得到一个更真实的测试工作的奇怪错误:

System.InvalidOperationException: Expression object should be not null.
   at Hangfire.Common.Job.FromExpression(LambdaExpression methodCall, Type explicitType)
   at Hangfire.RecurringJob.AddOrUpdate(String recurringJobId, Expression`1 methodCall, Func`1 cronExpression, TimeZoneInfo timeZone, String queue)
   at WsApplication.Web.Startup.Startup.ConfigureServices(IServiceCollection services) in C:\Projects\boxman\aspnet-core\src\WsApplication.Web.Host\Startup\Startup.cs:line 163
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

这是我在我的创业课上的:

        // Hangfire (Enable to use Hangfire instead of default job manager)
        services.AddHangfire(config =>
        {
            config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default"));
        });
        JobStorage.Current = new SqlServerStorage(_appConfiguration.GetConnectionString("Default"));

        // Register recurring jobs on startup
        var sp = services.BuildServiceProvider();
        var offHireJob = sp.GetService<UnsetContainerIsBookedPerOffHireJob>();
        // Test job 1 - this gets registered fine!
        RecurringJob.AddOrUpdate("Test", () => Console.Write("Test"), Cron.Minutely);
        // Test job 2 - This line triggers the error!
        RecurringJob.AddOrUpdate(UnsetContainerIsBookedPerOffHireJob.JobId, () => offHireJob.Run(), Cron.Minutely);

这是我的实际测试工作:

public class UnsetContainerIsBookedPerOffHireJob : ApplicationService
{
    public readonly static string JobId = nameof(UnsetContainerIsBookedPerOffHireJob);
    private readonly IRepository<ContractLineMovement, int> _contractLineMovementRepository;

    public UnsetContainerIsBookedPerOffHireJob(
        IRepository<ContractLineMovement, int> contractLineMovementRepository
    ){ 
        _contractLineMovementRepository = contractLineMovementRepository;
    }

    public void Run()
    {
        Logger.Debug("Running UnsetContainerIsBookedPerOffHireJob.Run()");

        var offHirequery = from contractLineMovement in _contractLineMovementRepository.GetAll()
                           where contractLineMovement.ContractWorkFlowEventId == (int)ContractWorkFlowEventValues.OffHire
                           select contractLineMovement;

        foreach (var offHire in offHirequery)
        {
            Logger.Debug("Processing offhire with ID: " + offHire.Id + " and Date: " + offHire.HireDate);
        }
    }
}

在 Hangfire 的源代码中找到了引发此异常的一段代码,但我仍然不明白为什么这个表达式

() => offHireJob.Run()

会导致问题。对我来说它看起来很基本。也许我错过了一些基本的东西?

或者有没有更好的方法在应用程序级别注册我的经常性工作?

标签: .net-corescheduled-taskshangfire

解决方案


推荐阅读