Quartz. Net расписание запускается из консольного приложения, но не из развернутой службы Topshelf windows - PullRequest
2 голосов
/ 24 января 2020

У меня есть сервис. NET windows, который использует TopShelf и Quartz. Net. Мои запланированные задания запускаются только при локальном запуске консольного приложения Topshelf (. NET framework 4.7.2). Когда я развертываю их как службу Windows на той же машине или на удаленной машине, триггеры не срабатывают. Что я делаю не так?

Вот код, который у меня есть:

class Program
{
    static void Main(string[] args)
    {
        var services = new ServiceCollection();

        var serviceProvider = Bootstrapper.GetServiceProvider(services);


        HostFactory.Run(configurator =>
        {
            configurator.SetServiceName("MyWindowsService");
            configurator.SetDisplayName("MyWindowsService");
            configurator.SetDescription("MyWindowsService");

            configurator.RunAsNetworkService();

            configurator.Service<MyWindowsService>(serviceConfigurator =>
            {
                var jobFactory = serviceProvider.GetRequiredService<IJobFactory>();

                serviceConfigurator.ConstructUsing(() => new MyWindowsService(jobFactory));

                serviceConfigurator.WhenStarted((service, hostControl) =>
                {
                    service.OnStart();
                    return true;
                });
                serviceConfigurator.WhenStopped((service, hostControl) =>
                {
                    service.OnStop();
                    return true;
                });
            });
        });
    }
}

А вот код загрузчика:

class Bootstrapper
{
    public static IServiceProvider GetServiceProvider(IServiceCollection services)
    {
        services.AddSingleton<IJobFactory>(provider =>
        {
            var jobFactory = new JobFactory(provider);
            return jobFactory;
        });

        services.AddTransient<DownloadJob>();            

        RegisterConfigurations(services);

        var serviceProvider = services.BuildServiceProvider();
        return serviceProvider;
    }

    public static void RegisterConfigurations(IServiceCollection services)
    {
        if (services == null)
        {
            return;
        }
    }
}

Вот Windows Служба:

public class MyWindowsService
{
    private readonly IJobFactory jobFactory;

    public MyWindowsService(IJobFactory jobFactory)
    {
        this.jobFactory = jobFactory;
    }

    public async void OnStart()
    {
        var schedulerFactory = new StdSchedulerFactory();
        var scheduler = await schedulerFactory.GetScheduler();
        scheduler.JobFactory = jobFactory;
        await scheduler.Start();
        ScheduleAllJobs(scheduler);
    }

    private async void ScheduleAllJobs(IScheduler scheduler)
    {
        var downloadJobDetails = GetDownloadJobDetails();
        var downloadTrigger = GetDownloadTrigger();
        await scheduler.ScheduleJob(downloadJobDetails, downloadTrigger);
    }

    private IJobDetail GetDownloadJobDetails()
    {
        return JobBuilder.Create<DownloadJob>()
            .WithIdentity(JobKey.Create("Downloader", "Download Job"))
            .Build();
    }

    private ITrigger GetDownloadTrigger()
    {
        return TriggerBuilder.Create()
            .WithIdentity(new TriggerKey("Downloader", "Download Job"))
            .StartNow()
            .WithSimpleSchedule(builder =>
            {
                builder.WithIntervalInSeconds(5)
                    .RepeatForever();
            })
            .Build();
    }

    public void OnStop()
    {

    }
}

Вот соответствующий код с работы:

public class DownloadJob : IJob
{
    public Task Execute(IJobExecutionContext context)
    {
        // Do something
        return Task.CompletedTask;
    }
}
...