基于文件存在的Quartz触发器?

时间:2014-06-30 18:32:20

标签: c# quartz-scheduler quartz.net

我是使用Quartz的新手,我对触发器有疑问。是否有可能基于文件存在触发?我想让Quartz运行一个工作,直到找到某个文件,然后停止运行该工作,或者转移到另一个工作。

例如,我想做这样的事情:

(1)Job1每隔60秒检查一次给定目录中是否存在File.txt。

(2)如果找到File.txt,则触发Job2启动。 Job1停止检查文件是否存在。

现在,我有:

// Job definitions
var Job1 = JobBuilder.Create<TestEmail>().WithIdentity("job1", "group1").Build();
var Job2 = JobBuilder.Create<TestFileTrigger>().WithIdentity("job2", "group2").Build();

// Triggers
ITrigger trigger1 = TriggerBuilder.Create()
      .WithIdentity("trigger1", "group1").StartNow()
      .WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever())
      .Build();

ITrigger trigger2 = TriggerBuilder.Create()
      .WithIdentity("trigger2", "group2").StartNow()
      .Build();

// Schedule jobs
scheduler.ScheduleJob(Job1, trigger1);
if (TestFileTrigger.fileExistence == true) 
{
     scheduler.ScheduleJob(Job2, trigger2);
}

但似乎Job2永远不会开始。

TestEmail和TestFileTrigger此时只需打印到控制台。布尔值TestFileTrigger.fileExistence来自检查文件是否存在于给定位置(它确实存在)。

编辑: TestFileTrigger.fileExistence是一个布尔值。如果有帮助,添加了Job1 / Job2的定义。

编辑: 我发现如果我将Thread.Sleep(TimeSpan.FromSeconds(x));放在if语句之前,if语句将在满足条件时运行。 (其中x是一些秒数。)为什么它在这种情况下有效,但不是这样?我不能总是知道要满足条件需要多少秒。

2 个答案:

答案 0 :(得分:1)

应用程序的类型是什么?

如果这是(例如,Windows服务) - 为了使调度程序保持活动状态以便它根据您的触发器挂起来执行作业,您需要执行以下操作:

ThreadStart start = SetupSchedules()
var thread = new Thread(start) { Name = "mysvc" }
thread.Start();

..这将进入Windows服务的override void OnStart(string[] args)方法。

SetupSchedules方法将是挂钩到Quartz作业的东西,并且会像(你在OP上面编写的代码会有一个良好的开端):

ISchedulerFactory factory = new StdSchedulerFactory();
JobScheduler = factory.GetScheduler();
JobScheduler.ScheduleJob(job1, trigger1);

这应该保持活着,以便它执行作业。我在这里省略了一堆东西,但希望这会给你一些指示,帮助我把它编织到你的应用程序中。

你还需要这样的东西:

private void ManageThread()
{
   var _thread = Thread.CurrentThread;
   while (!_threadMustStop) // false by default, set this to true in a 'shutdown' process
   {
       Thread.Sleep(10000);
   }
}

...您可以从SetupSchedules方法调用

答案 1 :(得分:0)

看起来您不了解此处涉及的并发和线程。

问题如下。

您的MAIN主题执行以下操作。

  1. 创建两个职位
  2. 给每个工作一个触发器
  3. 安排Job1开始
  4. 检查TestFileTrigger.fileExistence如果为true,则启动Job2(它为false,因此不会运行)。
  5. 然后线程池线程将启动Job1。最有可能设置TestFileTrigger.fileExistence = true。但主线程已经完成了它的工作。

    FIN。

    你什么时候回去查看TestFileTrigger.fileExistence是否属实。所以它的结果无关紧要。事实上,在得到结果之前,您正在检查结果。

    通过添加Thread.Sleep,您可以给job1足够的时间来完成并给出结果(job1以异步和并发方式运行,很明显您希望它同步运行)。想象一下,例如你告诉你的朋友弗雷德去商店购买比萨并把它放在你的桌子上(异步),然后马上转过身来,想知道为什么你桌上没有披萨。

    如果你自己去商店,买了一个比萨饼然后把它放在家里把它放在你的桌子上,然后把你的桌子上的披萨吃掉了,那就是同步。

    JobScheduler.ScheduleJob(job1, trigger1);可以异步工作。

    您应该创建一个作业来结束第4步并安排定期运行,或者使用内置的FileScanJob代替。