我对使用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打印到控制台即可。 bool 值TestFileTrigger.fileExistence来自检查文件是否存在于给定位置(它确实存在)。

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

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

最佳答案

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

问题如下。

您的MAIN线程执行以下操作。

  • 创建两个作业
  • 给每个作业一个触发器
  • 安排Job1启动
  • 检查TestFileTrigger.fileExistence,如果为true,则启动Job2(它为false,因此无法运行)。

  • 然后,线程池线程将启动Job1。最有可能设置TestFileTrigger.fileExistence = true。但是主线程已经完成了它的工作。

    鳍。

    您绝对不会回去检查TestFileTrigger.fileExistence是否为真。因此其结果无关紧要。您实际上是在获取结果之前先检查结果。

    通过添加Thread.Sleep,您可以给job1足够的时间来完成并获得结果(job1异步并发运行,很明显您希望它可以同步运行)。想象一下,例如,您告诉您的 friend 弗雷德去商店买披萨并将其放在 table 上(异步),然后立即转身,想知道为什么办公 table 上没有披萨。

    如果您自己去商店,买了一个比萨饼并将其带回家并放在您的办公 table 上,然后从办公 table 上吃比萨饼,那将是同步的。
    JobScheduler.ScheduleJob(job1, trigger1);确实异步工作。

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

    10-02 15:10