【发布时间】:2011-08-21 11:24:23
【问题描述】:
我打算编写一个 ASP.NET 页面来按需触发作业。目前,我正在使用 SimpleTrigger 类来触发作业,但 __Trigger 类都不支持对象类型作为 JobParameters 中的值,并且据我所知,WCF Tcp 绑定在挂钩下用于将参数传递给作业调度引擎。我想知道如何将自定义对象(可序列化)作为作业参数传递。 谢谢你的建议!
【问题讨论】:
标签: c# asp.net c#-3.0 quartz.net
我打算编写一个 ASP.NET 页面来按需触发作业。目前,我正在使用 SimpleTrigger 类来触发作业,但 __Trigger 类都不支持对象类型作为 JobParameters 中的值,并且据我所知,WCF Tcp 绑定在挂钩下用于将参数传递给作业调度引擎。我想知道如何将自定义对象(可序列化)作为作业参数传递。 谢谢你的建议!
【问题讨论】:
标签: c# asp.net c#-3.0 quartz.net
有两种方法可以传递一个可以在 Quartz 作业执行时检索到的对象:
在数据映射中传递实例。当您设置作业时,使用如下键将您的实例添加到地图中:
// Create job etc...
var MyClass _myInstance;
statusJob.JobDataMap.Put("myKey", _myInstance);
// Schedule job...
在作业的Execute() 方法中检索实例,如下所示:
public void Execute(IJobExecutionContext context)
{
var dataMap = context.MergedJobDataMap;
var myInstance = (MyClass)dataMap["myKey"];
或
在设置作业时将实例添加到调度程序上下文中,如下所示:
ISchedulerFactory schedFact = new StdSchedulerFactory();
_sched = schedFact.GetScheduler();
_sched.Start();
// Create job etc...
var MyClass _myInstance;
_sched.Context.Put("myKey", myInstance);
// Schedule job...
在作业的Execute() 方法中检索实例,如下所示:
public void Execute(IJobExecutionContext context)
{
var schedulerContext = context.Scheduler.Context;
var myInstance = (MyClass)schedulerContext.Get("myKey");
【讨论】:
[Serializable] 进行归属?
当您安排作业时,您可以在 JobDetail 对象上设置 JobDataMap 并将其传递给您的调度程序,quartz.net tutorial 中描述了一些限制。该作业可以通过以下方式访问数据:
JobDataMap dataMap = context.JobDetail.JobDataMap;
但是我更喜欢通过注入到作业中的存储库来访问我的作业配置。
【讨论】:
在多线程环境中,上面 Hillstuk 的回答让我得到了意想不到的结果。 这是我使用 Newtonsoft 的解决方案……享受
public void InitJob() {
MyClass data = new MyClass {Foo = “Foo fighters”};
/* a unique identifier for demonstration purposes.. Use your own concoction here. */
int uniqueIdentifier = new Random().Next(int.MinValue, int.MaxValue);
IJobDetail newJob = JobBuilder.Create<MyAwesomeJob>()
.UsingJobData("JobData", JsonConvert.SerializeObject(data))
.WithIdentity($"job-{uniqueIdentifier}", "main")
.Build();
}
/* the execute method */
public class MyAwesomeJob : IJob
{
public void Execute(IJobExecutionContext context)
{
var jobData = JsonConvert.DeserializeObject<MyClass>(context.JobDetail.JobDataMap.GetString("JobData"));
}
}
/* for completeness */
public class MyClass {
string Foo { get; set; }
}
【讨论】:
您可以将您的实例/对象放入 IJobDetail。
JobDataMap m = new JobDataMap();
m.Put("Class1", new Class1(){name="xxx"});
IJobDetail job = JobBuilder.Create<Job>()
.WithIdentity("myJob", "group1")
.UsingJobData(m)//class object
.UsingJobData("name2", "Hello World!")
.Build();
用法
public void Execute(IJobExecutionContext context)
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
Class1 class1 = (Class1)dataMap.Get("Class1");
string x = class1.name;
}
【讨论】:
我按照以下方式传递了对象
JobDetail job1 = JobBuilder.newJob(JobAutomation.class)
.usingJobData("path", path)
.withIdentity("job2", "group2").build();
CronTrigger trigger1 = TriggerBuilder.newTrigger()
.withIdentity("cronTrigger2", "group2")
.withSchedule(CronScheduleBuilder.cronSchedule("40 27 11 * * ?"))
.build();
通过以下代码行获取jobdatamap
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String path =dataMap.getString("path");
【讨论】: