从Quartz.net中正在运行的作业中获取数据

Dan*_*Dan 5 c# quartz.net

我正在尝试在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()这样的工作中途从工作中获取数据?

Raf*_*ski 8

在作业完成之前,工作数据更改似乎不可用.因此,请使用专用数据结构来监视作业状态.在下面的示例中,我使用一个简单的公共静态属性公开了状态信息,该属性StatusInfo可以随时用于日志记录作业.

还有一个小小的改变:我已经取代WriteAllLinesAppendAllLines.

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)

  • 看起来很有效。在那种情况下,JobDataMap到底有什么意义? (2认同)