.NET Core后台任务队列

本地配置:

.NET 8.0的WebApi项目,许多基础配置不在这里重复描述。

最开始考虑到响应时间采用的是多线程的方案,但是为了程序健壮性后面就改用任务队列了。

一、创建通用后台任务队列接口

首先,我们创建一个接口来定义后台任务队列的行为。

cs 复制代码
using Microsoft.Extensions.DependencyInjection;

namespace CS_FeedbackApi.IService
{
    public interface IBackgroundTaskQueue
    {
        void EnqueueTask(Func<IServiceProvider, Task> task);
        Func<IServiceProvider, Task> DequeueTask();
    }
}

二、实现通用后台任务队列

接下来,我们实现这个接口。这个队列将存储要执行的异步任务委托。

cs 复制代码
using CS_FeedbackApi.IService;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;

namespace CS_FeedbackApi.Service
{
    public class BackgroundTaskQueue : IBackgroundTaskQueue
    {
        private readonly ConcurrentQueue<Func<IServiceProvider, Task>> _tasks = new();

        public void EnqueueTask(Func<IServiceProvider, Task> task)
        {
            _tasks.Enqueue(task);
        }

        public Func<IServiceProvider, Task> DequeueTask()
        {
            _tasks.TryDequeue(out var task);
            return task;
        }
    }
}

三、创建新的后台服务来处理队列

这个新的后台服务会为每个任务创建一个新的依赖注入作用域,从而可以解决"服务被俘获"的问题。

cs 复制代码
using CS_FeedbackApi.IService;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace CS_FeedbackApi.Service
{
    public class QueuedHostedService : BackgroundService
    {
        private readonly ILogger<QueuedHostedService> _logger;
        private readonly IBackgroundTaskQueue _taskQueue;
        private readonly IServiceProvider _serviceProvider;

        public QueuedHostedService(IBackgroundTaskQueue taskQueue, ILogger<QueuedHostedService> logger, IServiceProvider serviceProvider)
        {
            _taskQueue = taskQueue;
            _logger = logger;
            _serviceProvider = serviceProvider;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("Queued Hosted Service is running.");

            while (!stoppingToken.IsCancellationRequested)
            {
                var workItem = _taskQueue.DequeueTask();

                if (workItem != null)
                {
                    try
                    {
                        _logger.LogInformation("Executing background task.");
                        // 为每个任务创建新的作用域来解析范围服务
                        using (var scope = _serviceProvider.CreateScope())
                        {
                            await workItem(scope.ServiceProvider);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Error occurred executing background task.");
                    }
                }
                else
                {
                    await Task.Delay(500, stoppingToken);
                }
            }

            _logger.LogInformation("Queued Hosted Service is stopping.");
        }
    }
}

四、更新 Program.cs 以注册新服务

需要在 Program.cs 中注册新的服务

cs 复制代码
//后台服务
builder.Services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
builder.Services.AddHostedService<QueuedHostedService>();

五、接口中的使用

在需要使用的代码块中,将具体方法进行如下替换即可

cs 复制代码
_taskQueue.EnqueueTask(async sp =>
{
    var authService = sp.GetRequiredService<IAuthService>();

    //这里替换为具体你所写好的方法
    await authService.SendTemplateTiJiaoAsync(model, result);
});
相关推荐
波力海苔夹心脆6751 小时前
C# 视觉检测实战:PLC 按钮触发 VisionPro 检测,OK 亮灯 / NG 灭灯(西门子 PLC,含界面显示与图片存档)
开发语言·经验分享·c#·自动化·视觉检测·.net
hez20103 小时前
一行代码在 .NET 项目里启用 Satori GC
c#·.net·.net core·gc·clr
QUDONG_biubiubiu6 小时前
.NET Runtime 6.0/7.0/8.0/9.0下载修复教程,软件打不开这样解决
.net·net runtime下载·net运行库修复·net runtime安装
宝桥南山7 小时前
.NET 11 - 尝试创建一下AGUIServer和AGUIClient(基于新版.NET SDK for AG-UI)
microsoft·ai·微软·c#·aigc·.net
波力海苔夹心脆6757 小时前
C# LINQ 入门到上手:一篇讲透查询语法、常用操作符与延迟执行(含示例与速查表
经验分享·c#·.net·solr·linq
小羊没烦恼!1 天前
Windows Azure Platform体验(1):Windows Azure
java·大数据·后端·python·flask·word·.net
CSharp精选营2 天前
IIS 后面挂 Kestrel,这 3 个配置错了就 502
kestrel·.net·iis配置
鑫 源2 天前
C#源码开源, 获取macOS 电池数据,包括iOS (xamarin开发)
c#·.net·xamarin
xiangcns4 天前
PDMS PiplineTool(三十)一堆小优化+一个彩蛋功能
.net·二次开发·pdms