如果之前的工作尚未完成,则跳过。石英网

问题描述 投票:0回答:1

我还有工作。每 5 秒运行一次。但如果作业需要超过 5 秒,我需要取消下一个作业并在完成后按计划运行下一个作业。

工作类别:

public class LoggerJob : IJob
{
    private readonly ILogger<LoggerJob> _logger;
    
    public LoggerJob(ILogger<LoggerJob> logger)
    {
        this._logger = logger;
    }
    
    public Task Execute(IJobExecutionContext context)
    { 
        //some logic here
        _logger.LogInformation($"Log Job: at {DateTime.Now} and Jobtype: {context.JobDetail.JobType}");
        return Task.CompletedTask;
    }
}

安排班级开始方法:

public async Task StartAsync(CancellationToken cancellationToken)
    {
        Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
        Scheduler.JobFactory = _jobFactory;


        _jobsMetadata?.ForEach(async jobMetadata =>
        {

            IJobDetail jobDetail = CreateJob(jobMetadata);

            ITrigger trigger = CreateTrigger(jobMetadata);

            await Scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);

        });
        await Scheduler.Start(cancellationToken);
    }

我尝试了这样的方法,但它只是阻止了其他作业的执行,并且它们等待直到锁定:

    public Task Execute(IJobExecutionContext context)
    {
        lock (_lock)
        {
            if (!_isRunning)
            {
                //somelogic
                _logger.LogInformation($"Log Job: at {DateTime.Now} and Jobtype: {context.JobDetail.JobType}");
            }
            else
            {
                _logger.LogInformation($"Job canceled at {DateTime.Now}");
                context.JobDetail.JobDataMap.Put("cancel", true);
            }
        }
        

        return Task.CompletedTask;
    }
c# scheduled-tasks quartz
1个回答
0
投票

使用锁控制作业执行可能会阻塞其他作业,从而导致效率低下。相反,请考虑使用带有取消标记的异步编程以获得更有效的解决方案。通过设置作业执行的超时时间,如果超过指定的时间限制,您可以取消作业。以下是如何调整代码以实现此方法:

public class LoggerJob : IJob
{
private readonly ILogger<LoggerJob> _logger;
private readonly CancellationTokenSource _cancellationTokenSource;

public LoggerJob(ILogger<LoggerJob> logger)
{
    _logger = logger;
    _cancellationTokenSource = new CancellationTokenSource();
}

public Task Execute(IJobExecutionContext context)
{
    // Set a timeout for the job execution
    var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5), _cancellationTokenSource.Token);

    // Execute the job logic asynchronously
    var jobTask = ExecuteJobLogic(context);

    // Wait for either the job completion or the timeout
    var completedTask = Task.WhenAny(jobTask, timeoutTask);

    // Handle the completed task
    return completedTask.ContinueWith(task =>
    {
        if (task == jobTask)
        {
            // Job completed before timeout, cancel the timeout
            _cancellationTokenSource.Cancel();
        }
        else
        {
            // Timeout occurred, log cancellation
            _logger.LogInformation($"Job canceled due to timeout at {DateTime.Now}");
        }
    });
}

private async Task ExecuteJobLogic(IJobExecutionContext context)
{
    try
    {
        // Your job logic goes here
        _logger.LogInformation($"Log Job: at {DateTime.Now} and Jobtype: {context.JobDetail.JobType}");
        await Task.Delay(/* Your job logic */);
    }
    catch (Exception ex)
    {
        // Handle any exceptions thrown by the job logic
        _logger.LogError(ex, "Error executing job");
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.