问题描述
在此Windows窗体应用程序中,我使用Quartz.NET的Scheduler在特定时间触发作业。 代码工作正常,但执行作业时出现问题,需要从作业创建的方法之外的表单中调用某些内容。 (textBox1.Text)不继承在触发作业上创建的方法内部。 (我认为这与Scheduler类是公共异步的事实有关,欢迎任何解释)
namespace TaxControl
{
public partial class TaxControl : Form
{
.........................................
public class Scheduler
{
public async void Start()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
IScheduler scheduler = await schedulerFactory.GetScheduler();
await scheduler.Start();
IJobDetail job = JobBuilder.Create<Job>()
.WithIdentity("job","group1")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("job","group1")
.WithCronSchedule("0 36 18 * * ?")
.Build();
await scheduler.ScheduleJob(job,trigger);
}
}
public class Job : IJob
{
Task IJob.Execute(IJobExecutionContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Task taskA = new Task(() => InfoControl());
taskA.Start();
return taskA;
}
public void InfoControl()
{
MessageBox.Show(textBox1.Text);
}
}
解决方法
此代码存在几个问题:
-
显然,
Job
类没有对此TextBox
实例的引用。通常,可以通过编写接受Job
引用的TextBox
构造函数来解决此问题。 -
但是,要使Quartz.Net使用参数化构造函数实例化该作业,您将需要使用this之类的东西来注入它,这通常也可以使用this之类的DI来完成,或this。
-
在非UI线程上访问
Control.Text
会引发异常,因此这意味着您需要access the actual property by dispatching the call to the UI thread,或者只是通过传递简单的{{1} }到您的string
。
您还可以将Job
传递给作业的构造函数,即返回Func<string>
的函数。此功能还需要在线程安全的情况下进行UI访问,但是它将使工作逻辑与实际的UI脱钩。