[英]Quartz.net in WCF
我有一个服务:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PremieraInteraction : ServiceInit, IPremieraInteraction
{
public PremieraInteraction()
{
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// construct job info
IJobDetail jobDetail = JobBuilder.Create<PremieraUpdate>().WithIdentity("PremieraUpdateJob").Build();
ITrigger trigger =
TriggerBuilder.Create().WithIdentity("PremieraUpdateTrigger").StartNow().WithSimpleSchedule(
x => x.WithIntervalInSeconds(10)).Build();
sched.ScheduleJob(jobDetail, trigger);
}
}
这是工作:
public class PremieraUpdate:IJob
{
public void Execute(IJobExecutionContext context)
{
Debug.WriteLine("Fire");
}
}
问题是它只能工作一次。 为什么调度程序不会每10秒重复一次?
一旦服务完成操作,调度程序很可能是垃圾收集的。 这是预期的,因为除了服务之外,您没有任何引用调度程序的内容。
通常,每次调用创建的WCF服务。 这意味着为每次调用服务创建了一个新的服务实例。 在大多数情况下,这很好,因为它有助于避免并发问题,但也可能令人困惑。
在您的情况下,您需要对调度程序的持久引用。 有很多方法可以做到这一点,从服务上的静态变量到知道所有调度程序及其生命周期的某种调度程序存储库。 这取决于您的使用情况。
只是为了测试,您可以向服务类添加静态字段。 在服务调用中对此进行实例化,并且调度程序应根据需要每10秒调用一次操作。
但这还取决于您托管服务的位置(Web服务,服务,控制台应用程序?)
我建议你在Global.asax.cs
的Application_Start
事件中实例化工厂和调度Application_Start
,并将它们存储在静态公共属性中。
public class Global : System.Web.HttpApplication
{
public static ISchedulerFactory Factory;
public static IScheduler Scheduler;
protected void Application_Start(object sender, EventArgs e)
{
Factory = new StdSchedulerFactory();
Scheduler = Factory.GetScheduler();
}
}
现在,在服务中,您可以通过Global
属性访问调度程序。
防爆。
Global.Scheduler
我希望您使用WCF服务将新作业安排到通常在Windows服务中运行的Quartz服务器。 您可以在一个方法中执行该操作,而不是在构造函数中调度作业,该方法将获取作业的详细信息并最终计划并运行它。
如果您使用此实现,则无需将服务标记为单例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.