Я пытаюсь настроить повторяющиеся задания Hangfire при запуске приложения (в Startup.cs
веб-приложения .NET.Core), чтобы мы могли быть уверены, что они всегда зарегистрированы. Мне удалось заставить его работать для фиктивной работы, но я получаю странную ошибку для более реальной тестовой работы:
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 ()
может вызвать проблемы. Это выглядит основным для меня. Может быть, мне не хватает чего-то простого?
Или есть ли лучший способ зарегистрировать мои текущие задания один раз на уровне приложения?