ASP.Net 带任务队列的核心后台服务,是否需要 Task.Delay?
ASP.Net Core Background Service with Task Queue, does it need a Task.Delay?
我已经按照 Microsoft 文档了解如何使用任务队列实现 BackgroundService
,但我注意到主循环中没有 Task.Delay
,这是一个问题还是仍然 运行 还好吗?
这是有问题的服务 class:
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);
}
}
此代码取自
答案在于如果在队列中没有任何内容时执行这段代码会发生什么。
var workItem = await TaskQueue.DequeueAsync(stoppingToken);
答案是什么都没有发生。这行代码不会一遍又一遍地执行,直到有东西出队。这就是为什么没有必要延迟。
在某些东西出列之前它也不会阻塞。
发生的情况是执行该方法的线程被释放以执行其他操作。没有线程专用于执行 DequeueAsync
。 (看到这个优秀的 post - There Is No Thread。)
当队列中出现要出列的项目时,将分配可用线程以恢复执行该方法。
DequeueAsync
仅在
时抛出异常
- 取消令牌已取消
- 队列的
Complete
方法被调用并且队列为空,这意味着您不再期望队列中出现任何内容。
我已经按照 Microsoft 文档了解如何使用任务队列实现 BackgroundService
,但我注意到主循环中没有 Task.Delay
,这是一个问题还是仍然 运行 还好吗?
这是有问题的服务 class:
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);
}
}
此代码取自
答案在于如果在队列中没有任何内容时执行这段代码会发生什么。
var workItem = await TaskQueue.DequeueAsync(stoppingToken);
答案是什么都没有发生。这行代码不会一遍又一遍地执行,直到有东西出队。这就是为什么没有必要延迟。
在某些东西出列之前它也不会阻塞。
发生的情况是执行该方法的线程被释放以执行其他操作。没有线程专用于执行 DequeueAsync
。 (看到这个优秀的 post - There Is No Thread。)
当队列中出现要出列的项目时,将分配可用线程以恢复执行该方法。
DequeueAsync
仅在
- 取消令牌已取消
- 队列的
Complete
方法被调用并且队列为空,这意味着您不再期望队列中出现任何内容。