代码之家  ›  专栏  ›  技术社区  ›  luke88

石英净取消令牌

  •  11
  • luke88  · 技术社区  · 6 年前

    在我的调度程序中,使用quartz实现。net v3,我正在尝试测试取消令牌的行为:

    ....
    IScheduler scheduler = await factory.GetScheduler();
    ....
    var tokenSource = new CancellationTokenSource();
    CancellationToken ct = tokenSource.Token;
    // Start scheduler
    await scheduler.Start(ct);
    // some sleep 
    await Task.Delay(TimeSpan.FromSeconds(60));
    // communicate cancellation
    tokenSource.Cancel();
    

    我有一个无限运行的测试作业 Execute 方法检查取消令牌:

    public async Task Execute(IJobExecutionContext context)
    {
        while (true)
        {
            if (context.CancellationToken.IsCancellationRequested)
            {
                context.CancellationToken.ThrowIfCancellationRequested();
            }
        }
    }
    

    我希望当 tokenSource.Cancel() 被解雇后,作业将进入 if 并引发异常。但它不起作用。

    2 回复  |  直到 2 年前
        1
  •  9
  •   Emre Kabaoglu    6 年前

    根据 documentation ,您应该使用 Interrupt 要取消的方法 Quartz 工作。

    NameValueCollection props = new NameValueCollection
    {
        { "quartz.serializer.type", "binary" }
    };
    StdSchedulerFactory factory = new StdSchedulerFactory(props);
    var scheduler = await factory.GetScheduler();
    await scheduler.Start();
    IJobDetail job = JobBuilder.Create<HelloJob>()
        .WithIdentity("myJob", "group1")
        .Build();
    ITrigger trigger = TriggerBuilder.Create()
        .WithIdentity("myTrigger", "group1")
        .StartNow()
        .WithSimpleSchedule(x => x
            .WithRepeatCount(1)
            .WithIntervalInSeconds(40))
        .Build();
    await scheduler.ScheduleJob(job, trigger);
    //Configure the cancellation of the schedule job with jobkey
    await Task.Delay(TimeSpan.FromSeconds(1));
    await scheduler.Interrupt(job.Key);
    

    计划作业类别;

    public class HelloJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            while (true)
            {
                if (context.CancellationToken.IsCancellationRequested)
                {
                    context.CancellationToken.ThrowIfCancellationRequested(); 
                    // After interrupt the job, the cancellation request activated
                }
            }
        }
    }
    

    申请 scheduler.Interrupt 作业执行后,quartz将终止作业。

    编辑

    根据 source code (第2151行) 打断 方法应用作业执行上下文的取消标记。所以,最好利用图书馆的设施。

        2
  •  2
  •   Kit    4 年前

    以下是Github Repo的单元测试: https://github.com/quartznet/quartznet/blob/master/src/Quartz.Tests.Unit/InterrubtableJobTest.cs

    我试图以同样的方式取消,但对我来说也不起作用。

    @Storm斗篷我必须检查取消请求,因为我想对作业执行一些中止操作,例如将状态数据写入数据库。

    编辑:

    因此,在多次测试和实现之后。我已经开始运行了。

    这里有一些伪代码:

        this.scheduler = await StdSchedulerFactory.GetDefaultScheduler();
        this.tokenSource = new CancellationTokenSource();
        this.token = tokenSource.Token;
        // Start scheduler.
        await this.scheduler.Start(token);
        // add some jobs here
        // ...
        // cancel running jobs.
        IReadOnlyCollection<IJobExecutionContext> jobs = await this.scheduler.GetCurrentlyExecutingJobs();
        foreach (IJobExecutionContext context in jobs)
        {
           result = await this.scheduler.Interrupt(context.JobDetail.Key, this.token);
        }
        await this.scheduler.Shutdown(true);
    

    因此,现在可以在Execute方法中使用CancellationToken。