从Quartz.net运行AsyncTask

问题描述

我有一个定期运行的石英作业,在执行过程中,我将通过HttpClient提交一个rest api请求。当前,如果其余api“调用”失败(例如错误的请求状态代码400),它将“重新发送”相同的api调用,例如2-4次。这种行为不是“正确的”,我只想记录rest api调用的结果,因为我不希望在原始触发时间之后执行postasync请求。

  • 所以这基本上是“伪代码”,我只是通过石英作业创建了一堆报告,然后发送它们。
  • 当createreport失败,以某种方式“重新发送”请求时会发生问题(我在等待后从createReport函数登录,并且看到请求重新发送/响应再次收到)
  • 我对此很陌生,所以我不确定重试机制是否已经被烘焙到异步等待中,或者石英本身。
class Job : IJob
{
    public async Task Execute(IJobExecutionContext context)
    {
        var tasks = Enumerable.Range(0,count).Select(index => CreateReport(index));
        try
        {
            await Task.WhenAll(tasks);
        }
        catch { }
    }

    public static async Task CreateReport(int index)
    {
        var response = await ReportApi.PostAsync($"api/createReport/...",null);
    }
}

解决方法

在这种情况下,理想情况下,您将为模型建模更像消息传递。您可以有一个作业,但是可以为每个调用该作业的报表创建一个触发器,可以将“报告ID /用户ID /等”作为参数来触发作业数据映射。这样,一次只报告一份就可以解决问题。

现在,如果您的工作失败,则默认情况下将重试。您可以通过在逻辑周围进行try-catch来禁止这种情况,并在发生错误引发JobExecutionException时允许通过其属性来设置逻辑条件,例如UnscheduleFiringTrigger可以使它停止再次尝试-这是用于单发扳机,该扳机在施杜勒跑步过程中不会再触发。

通常,我会建议在外部资源(例如数据库)中进行状态管理(已生成报告)。然后在触发器中检查什么是正确的操作。也像注释中建议的那样,重试库可能允许进行更细粒度的操作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...