如何为BackgroundService的ExecuteAsync设置超时时间?

3

我有一个名为“Worker”的BackgroundService,我覆盖了ExecuteAsync方法以每10秒运行一些东西。有时候,我运行的内容持续时间很长。在这种情况下,我想要终止正在运行的内容,然后重新运行它。我该如何实现?

我的BackgroundService如下所示:

    public class Worker : BackgroundService {
        private readonly ITask task;
        private readonly IHostApplicationLifetime appLifeTime;

        public Worker(ITask task, IHostApplicationLifetime appLifeTime) {
            this.task = task;
            this.appLifeTime = appLifeTime;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
            while (!stoppingToken.IsCancellationRequested)
            {
                try {
                    this.task.Execute(stoppingToken);
                } catch (Exception e) {
                    this.appLifeTime.StopApplication();
                }

                await Task.Delay(10000, stoppingToken);
            }
        }
    }

    public interface ITask {
        void Execute(CancellationToken stoppingToken);
    }


2
传递一个 CancellationToken,在 X 时间后取消。将其与主机的停止令牌结合使用。检查哪个令牌被取消,然后停止应用程序或重试。只有在您的任务实际尊重令牌时才能明显地工作... - pinkfloydx33
CancellationTokenSource有CancelAfter()方法。 - Berkay Yaylacı
在我看来,Execute 真的需要返回一个可等待的任务(Task),而不是 void。这样做会使事情变得更容易。 - pinkfloydx33
1个回答

2
您可以按照以下方式进行操作:
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
    var cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
    cancellationSource.CancelAfter(10000);
    
    return Task.Run(() => task.Execute(cancellationSource.Token));
}

如果你想处理异常和/或等待任务,那么你可以这样做,但这只是一个简单的例子。


您是正确的,抱歉我过于简化了。我已经编辑了答案。 - Francesco D.M.
1
另外,我认为如果 ITask.Execute 方法返回一个 Task 会更好。 - Francesco D.M.
糟糕,方法签名中漏掉了void...但是现在,如果主机停止,两个任务都不会停止。 - pinkfloydx33
1
可以使用 CancellationTokenSource.CreateLinkedTokenSource 来链接取消标记(cancellation tokens),如果需要的话。我不想在这里给出太多具体细节,因为它真的取决于用户的情况。 - Francesco D.M.
我用上述提到的方法简化了事情。这应该有效,但我没有测试它。 另外,如果“ITask.Execute”方法返回一个“Task”,就可以避免使用Task.Run - Francesco D.M.
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接