I am attempting to run multiple jobs with Quartz.NET and Topshelf using C#.
HostFactory.Run(c =>
{
c.ScheduleQuartzJobAsService(q =>
q.WithJob(() => JobBuilder.Create<TypeA>().Build())
.AddTrigger(() => TriggerBuilder.Create().WithSimpleSchedule(builder => builder.WithIntervalInSeconds(ConfigurationSettings.AppFrequencyInSeconds).RepeatForever()).Build())
).StartAutomatically().
ScheduleQuartzJobAsService(r =>
r.WithJob(() => JobBuilder.Create<TypeB>().Build())
.AddTrigger(() => TriggerBuilder.Create().WithSimpleSchedule(builder => builder.
WithIntervalInSeconds(ConfigurationSettings.AppFrequencyInSeconds).RepeatForever()).Build())
).StartAutomatically();
c.StartAutomatically();
c.SetServiceName("ServiceName");
});
Using the above code, only the execute method in TypeB gets executed. I have also tried:
HostFactory.Run(c =>
{
c.ScheduleQuartzJobAsService(q =>
q.WithJob(() => JobBuilder.Create<TypeA>().Build())
.AddTrigger(() => TriggerBuilder.Create().WithSimpleSchedule(builder => builder.
WithIntervalInSeconds(ConfigurationSettings.AppFrequencyInSeconds).RepeatForever()).Build())
).StartAutomatically();
c.StartAutomatically();
c.SetServiceName("Service1");
c.ScheduleQuartzJobAsService(r =>
r.WithJob(() => JobBuilder.Create<TypeB>().Build())
.AddTrigger(() => TriggerBuilder.Create().WithSimpleSchedule(builder => builder.
WithIntervalInSeconds(ConfigurationSettings.AppFrequencyInSeconds).RepeatForever()).Build())
).StartAutomatically();
c.StartAutomatically();
c.SetServiceName("Service2");
});
With this code, only the execute method in TypeB is called. Both my classes TypeA and TypeB have 'Execute' methods which are the entry points for each class (which do get called if they are part of a job on their own). It seems that whichever service code is second is the one that is always called - if I swap the order of these two ScheduleQuartzJobAsService calls it is always the class in the second call that is executed.
How can I write my HostFactory.Run method so both jobs are executed concurrently?
HostFactory.Run(c =>
{
c.Service<ContainerService>(s =>
{
s.ConstructUsing(name => new ContainerService());
s.WhenStarted((service, control) => service.Start());
s.WhenStopped((service, control) => service.Stop());
s.ScheduleQuartzJob<ContainerService>(q =>
q.WithJob(() =>
JobBuilder.Create<TypeA>().Build())
.AddTrigger(() =>
TriggerBuilder.Create()
.WithSimpleSchedule(builder => builder
.WithIntervalInSeconds(20)
.RepeatForever())
.Build())
);
s.ScheduleQuartzJob<ContainerService>(q =>
q.WithJob(() =>
JobBuilder.Create<TypeB>().Build())
.AddTrigger(() =>
TriggerBuilder.Create()
.WithSimpleSchedule(builder => builder
.WithIntervalInSeconds(60)
.RepeatForever())
.Build())
);
});
});
...
public class ContainerService
{
public bool Start()
{
return true;
}
public bool Stop()
{
return true;
}
}
My problem was I was mixing up the concepts of the service and job classes. As soon as I introduced my ContainerService
with Start()
and Stop()
bool methods that returned true, and I called ScheduleQuartzJob
rather than ScheduleQuartzJobAsService
the above code worked for me as my TypeA
and TypeB
already implemented IJob
.