quartz.net срабатывает дважды

#c# #asp.net #scheduled-tasks #quartz.net

#c# #asp.net #запланированные задачи #quartz.net

Вопрос:

У меня есть quartz.net интегрирован в asp.net приложение mvc.

У меня запланировано, что он будет запускаться один раз в день рано утром. В большинстве случаев мой пример задания срабатывает 2 раза

 2011-06-06 04:00:00.0077|INFO| -> once
2011-06-06 04:00:00.0233|INFO| -> twice
  

Но случилось так, что он срабатывает только один раз, но редко (на самом деле только один раз).

Мне любопытно выяснить, почему это происходит, или также в предложениях о том, как устранить это событие (это происходит в размещенной среде)

Это точки интеграции:

Global.Asax.cs

 protected void Application_Start()
{
ISchedulerFactory factory = new StdSchedulerFactory()    
IScheduler scheduler = factory.GetScheduler();    
scheduler.Start();    
}
  

web.config

   <configSections>
    <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </configSections>

  <quartz>
     <add key="quartz.scheduler.instanceName" value="JobScheduler" />

    <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
    <add key="quartz.threadPool.threadCount" value="10" />
    <add key="quartz.threadPool.threadPriority" value="Normal" />


    <add key="quartz.jobStore.misfireThreshold" value="60000" />
    <add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz" />


    <add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.JobInitializationPlugin, Quartz" />
    <add key="quartz.plugin.xml.fileNames" value="~/jobs.config" />

  </quartz>
  

jobs.config

 <quartz xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" overwrite-existing-jobs="true">

  <job>
      <job-detail>
       <name>SampleJob</name>
       <group>SampleJobs</group>
       <description>sample</description>
      <job-type>Services.SampleJob, Sample</job-type>
      <volatile>false</volatile>
      <durable>true</durable>
      <recover>false</recover>
    </job-detail>

    <trigger>
      <cron>
        <name>SampleJobTrigger</name>
        <group>SampleJobs</group>
        <description>Description</description>
        <job-name>SampleJob</job-name>
        <job-group>SampleJobs</job-group>
        <cron-expression>0 0 4 * * ? *</cron-expression>
      </cron>
    </trigger>
   </job>
</quartz>
  

Любая помощь или указатели высоко оценены

—MB

Ответ №1:

На самом деле трудно сказать. Кажется, все в порядке.
Я бы посоветовал вам сделать вашу фабрику и планировщик одноэлементными (так и должно быть) и посмотреть, что произойдет:

 public class MyScheduler
{
    static MyScheduler()
    {
        _schedulerFactory = new StdSchedulerFactory(getProperties());
        _scheduler = _schedulerFactory.GetScheduler();
    }
    public static IScheduler GetScheduler()
    {
        return _scheduler;
    }

    private static readonly ISchedulerFactory _schedulerFactory;
    private static readonly IScheduler _scheduler;
 }
  

Если мы хотим передать некоторые свойства нашему планировщику, мы можем использовать файл конфигурации или:

 private static NameValueCollection getProperties()
{
    var properties = new NameValueCollection();

    properties["quartz.scheduler.instanceName"] = "MyScheduler";
    properties["quartz.scheduler.instanceId"] = "Web";

    // Configure Thread Pool 
    properties["quartz.threadPool.type"] = "Quartz.Simpl.ZeroSizeThreadPool, Quartz";

    // Configure Job Store -->
    properties["quartz.jobStore.misfireThreshold"] = "60000";

    properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";
    properties["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz";
    properties["quartz.jobStore.useProperties"] = "true";
    properties["quartz.jobStore.dataSource"] = "default";
    properties["quartz.jobStore.tablePrefix"] = "QRTZ_";
    properties["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz";
    properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz";

    properties["quartz.dataSource.default.provider"] = "SqlServer-20";
    properties["quartz.dataSource.default.connectionString"] = "<connection string>";   

    return properties;
}
  

Комментарии:

1. Что находится в get Properties?

Ответ №2:

Ваша работа выполняется очень быстро.

Попробуйте добавить System.Threading.Thread.Sleep(1000) и сработает только один раз.

Спасибо!

Ответ №3:

Это старая заявка, на которую был получен ответ. Но сегодня я столкнулся с этим в тестовой среде и отыскал возможную причину.

Мы запускаем несколько серверов приложений. Предполагается, что задания будут выполняться только из App1. Но каким-то образом конфигурация App2 была нарушена, поэтому она не только выполняла задания, но и записывала в файлы журнала App1.

Таким образом, это выглядело так, как будто App1 запускал задания дважды, с интервалом в миллисекунды. Именно то, что было в исходном сообщении.