0

我有一个服务:

[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 秒重复一次?

4

2 回答 2

1

一旦服务完成操作,调度程序很可能会被垃圾收集。这是符合预期的,因为除了服务之外,您没有任何引用调度程序的东西。

通常是按调用创建的 WCF 服务。这意味着每次调用服务都会创建一个新的服务实例。在大多数情况下,这很好,因为它有助于避免并发问题,但它也可能令人困惑。

在您的情况下,您需要对调度程序的持久引用。有很多方法可以做到这一点,从服务上的静态变量到某种了解所有调度程序及其生命周期的调度程序存储库。这取决于您的使用情况。

只是为了测试,您可以在服务类中添加一个静态字段。在服务调用中实例化这一点,调度程序应根据需要每 10 秒调用一次操作。

但这也取决于您托管服务的位置(Web 服务、服务、控制台应用程序?)

于 2012-06-14T12:29:20.190 回答
1

我建议您在发生的情况下实例化工厂和调度程序Application_Start并将Global.asax.cs它们存储在静态公共属性中。

  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 服务器。除了在构造函数中调度作业,您可以在一个方法中执行此操作,该方法将获取作业的详细信息并最终调度并运行它。

如果您使用此实现,则无需将服务标记为单例。

于 2012-06-14T12:53:23.263 回答