带有任务队列的ASP.Net Core后台服务,是否需要Task.Delay?

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

我已按照 Microsoft 文档了解如何使用任务队列实现

BackgroundService
,但我注意到主循环中没有
Task.Delay
,这是一个问题还是仍然可以正常运行?

这是有问题的服务类别:

public class BackgroundTasksService : BackgroundService
{
    public IBackgroundTaskQueue TaskQueue { get; }

    public BackgroundTasksService(IBackgroundTaskQueue taskQueue)
    {
        TaskQueue = taskQueue;
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await BackgroundProcessing(stoppingToken);
    }

    private async Task BackgroundProcessing(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var workItem =
                await TaskQueue.DequeueAsync(stoppingToken);

            try
            {
                await workItem(stoppingToken);
            }
            catch (Exception ex)
            {
            }
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        await base.StopAsync(stoppingToken);
    }
}

此代码取自

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0&tabs=visual-studio#queued-background-tasks

c# .net api asp.net-core background-service
1个回答
4
投票

答案在于如果在队列中没有任何内容时执行此代码会发生什么。

var workItem = await TaskQueue.DequeueAsync(stoppingToken);

答案是什么也没有发生。这行代码不会一遍又一遍地执行,直到某些内容出队为止。这就是为什么不需要延迟。

在某些内容出队之前它也不会阻塞。

发生的情况是执行该方法的线程被释放以执行其他操作。没有线程专门用于执行

DequeueAsync
。 (请参阅这篇优秀的帖子 - 没有线程。)

当队列中出现要出队的项目时,则会分配一个可用线程来恢复该方法的执行。

DequeueAsync
仅在以下情况下抛出异常:

  • 取消令牌被取消
  • 队列的
    Complete
    方法被调用 并且队列为空,这意味着您不再期望队列中出现任何内容。
© www.soinside.com 2019 - 2024. All rights reserved.