我需要安排一个触发器每分钟触发一次,如果作业仍在运行,则下一分钟触发器不应该触发,应该再等一分钟检查,如果作业完成,触发器应该触发谢谢
5 回答
在 Quartz 2 中,您需要DisallowConcurrentExecution
在工作类上使用该属性。然后确保您使用类似于TriggerBuilder.Create().WithIdentity( "SomeTriggerKey" )
as的方式设置密钥DisallowConcurrentExecution
来确定您的作业是否已经在运行。
[DisallowConcurrentExecution]
public class MyJob : IJob
{
...
}
我没有找到任何关于 monitor.enter 或类似的东西,感谢任何其他答案是作业应该实现“StatefulJob”接口。作为 StatefulJob,只要一个实例已经在运行,另一个实例就不会运行再次感谢
IStatefulJob 是这里的关键。当您参与线程时,创建自己的锁定机制可能会导致调度程序出现问题。
如果您使用的是 Quartz.NET,您可以在 Execute 方法中执行以下操作:
object execution_lock = new object();
public void Execute(JobExecutionContext context) {
if (!Monitor.TryEnter(execution_lock, 1)) {
return,
}
// do work
Monitor.Exit(execution_lock);
}
我把这个从我的头顶上拉下来,也许有些名字是错误的,但这就是想法:在你执行时锁定某个对象,如果在执行时锁定是打开的,那么之前的作业仍在运行,你只需return;
编辑: Monitor 类位于 System.Threading 命名空间中
如果您使用的是 springquartz 集成,则可以从 MethodInvokingJobDetailFactoryBean 将“concurrent”属性指定为“false”
<bean id="positionFeedFileProcessorJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="xxxx" />
<property name="targetMethod" value="xxxx" />
<property name="concurrent" value="false" /> <!-- This will not run the job if the previous method is not yet finished -->
</bean>