在 ASP.NET Core Web Minimal API 中运行单独的进程

Dav*_*vid 3 c# task-parallel-library asp.net-web-api asp.net-core asp.net-core-minimal-hosting-model

我有一个长时间运行的进程,我想向其中添加 REST api。通过 API,我希望能够检查长时间运行的进程中变量的值。

我使用最少的 API 整理了一个概念验证:

public class Program
{
    public static int val = 0;
    public static object locker = new object();


    public static void Main(string[] args)
    {
        Task.Run(() =>
        {
            while (true)
            {
                lock (locker)
                {
                    val++;
                }
                Thread.Sleep(100);
            }
        });

        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();

        app.MapGet("/", () => 
        {
            lock (locker)
                return val;
        });

        app.Run();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的想法是让我的长时间运行进程的代码在 Task.Run 中运行。我以正确的方式处理这件事吗?我想做的事情是否有任何潜在的陷阱/陷阱?

小智 5

您可以创建一个保存状态的服务,并且可以从 API 访问该服务。Windows 服务/托管服务非常适合“长时间运行的进程”,并且它可以托管您的 API:文档

ValueService.cs

BackgroundService为您的长期运行流程实施。

public class ValueService : BackgroundService
{
    private int _val;

    public int Value
    {
        get { return _val; }
        set { _val = value; }
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {        

        while (!stoppingToken.IsCancellationRequested)
        {
            await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
            Value++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

程序.cs

注册您的服务并从服务提供商处注册检索。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ValueService>();
builder.Services.AddHostedService(p => p.GetService<ValueService>()!);

var app = builder.Build();  
    
Run Code Online (Sandbox Code Playgroud)

在您的 API 中注入服务:

app.MapGet("/", (ValueService valueService) =>
{
    return valueService.Value;       
});

app.Run();
Run Code Online (Sandbox Code Playgroud)