我正在尝试在Quartz.net中创建一个工作,它将监视所有其他工作的状态并定期更新日志文件.它只会在作业完成执行后从作业中获取数据,但我正在尝试获取作业状态的动态信息.
我写了尽可能简单的测试工作,测试一半工作(这是令人沮丧的,因为我无法分辨实际代码中有什么不同).这是测试代码:
工作
[PersistJobDataAfterExecution]
[DisallowConcurrentExecution]
class SimpleFeedbackJob : IInterruptableJob
{
private DateTime _lastRun;
public string LastRun { get { return _lastRun.ToString(); } }
private string _status;
public void Interrupt()
{
}
public void Execute(IJobExecutionContext context)
{
_status = "working";
_lastRun = DateTime.Now;
JobDataMap jobData = context.JobDetail.JobDataMap;
jobData["time"] = LastRun;
jobData["status"] = _status;
DateTime n = DateTime.Now.AddSeconds(5);
while (DateTime.Now < n) { }
//Thread.Sleep(5000);
_status = "idle";
jobData["status"] = _status;
}
}
public class LogUpdaterJob : IInterruptableJob
{
private IScheduler _scheduler = TaskManager.Scheduler; //This is the same scheduler that will call this task :/
private string _filepath = Configs.BasePath + @"Logs\log.txt";
public void Execute(IJobExecutionContext context)
{
Func<string, string> UpdatedLineData
= name =>
{
JobKey jobKey = _scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupContains("test")).Where(k => k.Name == name).First();
IJobDetail job = _scheduler.GetJobDetail(jobKey);
ITrigger trigger = _scheduler.GetTriggersOfJob(jobKey).First();
string status = job.JobDataMap.Get("time") as string;
string time = job.JobDataMap.Get("status") as string;
return string.Format("{0,-25} {1,-25}", time, status);
};
List<string> lines = new List<string>();
lines.Add(UpdatedLineData("feedback_test"));
File.WriteAllLines(_filepath, lines);
}
public void Interrupt()
{
}
}
Run Code Online (Sandbox Code Playgroud)
来自的相关摘录 TaskScheduler
private static IScheduler _scheduler = StdSchedulerFactory.GetDefaultScheduler();
public static IScheduler Scheduler { get { return _scheduler; } }
public void Run()
{
_scheduler.Start();
IJobDetail feedbackJob = JobBuilder.Create<SimpleFeedbackJob>()
.WithIdentity("feedback_test", "test")
.UsingJobData("time", "")
.UsingJobData("status", "")
.Build();
ITrigger feedbackTrigger = TriggerBuilder.Create()
.WithIdentity("feedback_test", "test")
.WithSimpleSchedule(x => x.WithIntervalInSeconds(10)
.RepeatForever())
.Build();
IJobDetail loggerJob = JobBuilder.Create<LogUpdaterJob>()
.WithIdentity("LogUpdater", "Admin")
.Build();
ITrigger loggerTrigger = TriggerBuilder.Create()
.WithIdentity("LogUpdater", "Admin")
.WithSimpleSchedule(x => x.WithIntervalInSeconds(1)
.RepeatForever())
.Build();
_scheduler.ScheduleJob(feedbackJob, feedbackTrigger);
_scheduler.ScheduleJob(loggerJob, loggerTrigger);
}
Run Code Online (Sandbox Code Playgroud)
所以这会输出一些数据log.txt,它会使最后一次运行时间正确,但它只会显示"idle"我认为它应该是"working"一半时间的状态.换句话说,我希望在作业仍在运行时写入和访问作业数据.
是否可以通过Execute()这样的工作中途从工作中获取数据?
在作业完成之前,工作数据更改似乎不可用.因此,请使用专用数据结构来监视作业状态.在下面的示例中,我使用一个简单的公共静态属性公开了状态信息,该属性StatusInfo可以随时用于日志记录作业.
还有一个小小的改变:我已经取代WriteAllLines了AppendAllLines.
class StatusInfo
{
public DateTime LastRun;
public string Status;
}
[PersistJobDataAfterExecution]
[DisallowConcurrentExecution]
class SimpleFeedbackJob : IInterruptableJob
{
public static StatusInfo StatusInfo;
static SimpleFeedbackJob()
{
SetStatus("idle");
}
public void Interrupt()
{
}
public void Execute(IJobExecutionContext context)
{
SetStatus("working");
Thread.Sleep(5000);
SetStatus("idle");
}
private static void SetStatus(string status)
{
StatusInfo = new StatusInfo
{
LastRun = DateTime.Now,
Status = status
};
}
}
class LogUpdaterJob : IInterruptableJob
{
private string _filepath = @"D:\Temp\Logs\log.txt";
public void Execute(IJobExecutionContext context)
{
List<string> lines = new List<string>();
var statusInfo = SimpleFeedbackJob.StatusInfo;
lines.Add(String.Format("{0,-25} {1,-25}",
statusInfo.LastRun,
statusInfo.Status));
File.AppendAllLines(_filepath, lines);
}
public void Interrupt()
{
}
}
Run Code Online (Sandbox Code Playgroud)