我在Windows服務中使用Quartz.Net來處理我將運行的各種作業的調度。這些作業位於數據庫內部,每個作業都由單獨的類庫內的工廠方法處理。在Quartz.net中,如何在使用單個IJob時阻止同時運行的作業?
我想阻止調度程序在一次運行超過1個作業,但是我不能使用[DisallowConcurrentExecution]
屬性,因爲我在調度程序中只有一個IJob
- 我的工廠方法在單獨的庫中處理決定要運行什麼工作。
下面是我的一個IJob
:
public void Execute(IJobExecutionContext context)
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
int jobId = dataMap.GetInt("JobId");
logger.InfoFormat("Job {0} has been triggered.", jobId);
//Create a new Job Instance
JobInstance jobInstance = new JobInstance()
{
CreateDate = DateTime.UtcNow,
ExecutionState = ExecutionState.Running,
CreateSource = "Agent Scheduler Service",
Job = new Job() { Id = jobId }
};
middlewareRepository.CreateJobInstance(jobInstance);
var job = jobFactory.GetJobImplementation(jobInstance);
//execute the job
job.Execute();
logger.InfoFormat("Job {0} has been executed.", jobId);
}
在此,有一個jobId
這是我對我的工作重點,我想只允許一個實例在任何給定時間運行。
這是我的加載工作:
protected void LoadJobs()
{
logger.Info("Loading jobs.");
var jobs = middlewareRepository.GeActiveJobs();
foreach (var job in jobs)
{
IJobDetail jobDetail = JobBuilder.Create<JobDespatcher>()
.WithIdentity(job.Description)
.UsingJobData("JobId", job.Id)
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithCronSchedule(job.CronExpression)
.Build();
scheduler.ScheduleJob(jobDetail, trigger);
logger.InfoFormat("Job with id {0} ({1}) has been scheduled.", job.Id, job.Description);
}
}
是否有內Quartz.net的方式,以防止運行基於密鑰或數據塊的兩次同樣的工作嗎?
您是否熟悉如何在.net中鎖定?如果沒有,這聽起來像你想看看。鎖定關鍵字(https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement)允許一次只輸入一小部分代碼(並且將等到需要的時候其他人都離開了)。 Monitor.TryEnter(https://msdn.microsoft.com/en-us/library/system.threading.monitor.tryenter(v=vs.110).aspx)將允許您跳過執行代碼,如果其他人已經運行它... – Chris
您可以嘗試設置quartz.net線程池中的線程數等於1.在web.config文件中,在石英部分添加next: '' –
Set
@設置將阻止所有作業同時運行。我希望儘可能多的IJob在IJob I中運行,但我有一個「Job Group」,並且只希望工作組中的一種類型的作業在任何時候都可以運行 – Lock