简体   繁体   English

如何在 ASPNET Core 3.0 中启动后台进程?

[英]How do you launch a background process in ASPNET Core 3.0?

I know that the new ASPNET Core 3.0 stack has a number of improvements around hosting processes.我知道新的 ASPNET Core 3.0 堆栈在托管进程方面有许多改进。

I am curious about the best way to be able to define and execute a background process from a Razor PageModel?我很好奇能够从 Razor PageModel 定义和执行后台进程的最佳方式? Meaning I have some logic that needs to start something in the background and then that Razor page doesn't need to monitor it's outcome, but I would like to be able to observe it too if that's not too hard.这意味着我有一些逻辑需要在后台启动一些东西,然后 Razor 页面不需要监控它的结果,但如果这不太难的话,我也希望能够观察它。

Can someone show me a code sample or point me in the right direction?有人可以向我展示代码示例或指出正确的方向吗?

Since this is probably a follow-up from your previous question about IHostedService , I am going to assume that you want to have some background service (as a hosted service) within your ASP.NET Core application that is able to perform background tasks.由于这可能是您之前关于IHostedService问题的后续内容,我将假设您希望在您的 ASP.NET Core 应用程序中拥有一些能够执行后台任务的后台服务(作为托管服务)。 And now you want to trigger such a task through a controller or Razor page action and have it executed in the background?现在您想通过控制器或 Razor 页面操作触发这样的任务并让它在后台执行吗?

A common pattern for this is to have some central storage that keeps track of the tasks which both the background service and the web application can access.一个常见的模式是有一些中央存储来跟踪后台服务和 Web 应用程序都可以访问的任务。 A simple way to do this is to make it a (thread-safe) singleton service that both sides can access.一种简单的方法是使其成为双方都可以访问的(线程安全的)单例服务。

The docs actually show a simple example using a BackgroundTaskQueue which is exactly that shared service/state.文档实际上显示了一个使用BackgroundTaskQueue的简单示例,这正是共享服务/状态。 If you have a worker for a specific kind of job though, you could also implement it like this:如果你有一个特定类型工作的工人,你也可以像这样实现它:

public class JobQueue<T>
{
    private readonly ConcurrentQueue<T> _jobs = new ConcurrentQueue<T>();
    private readonly SemaphoreSlim _signal = new SemaphoreSlim(0);

    public void Enqueue(T job)
    {
        _jobs.Enqueue(job);
        _signal.Release();
    }

    public async Task<T> DequeueAsync(CancellationToken cancellationToken = default)
    {
        await _signal.WaitAsync(cancellationToken);
        _jobs.TryDequeue(out var job);
        return job;
    }
}

You can then register an implementation of this with the service collection along with a hosted background service that works on this queue:然后,您可以使用服务集合以及在此队列上运行的托管后台服务注册此实现:

services.AddSingleton<JobQueue<MyJob>>();
services.AddHostedService<MyJobBackgroundService>();

The implementation of that hosted service could then look like this:该托管服务的实现可能如下所示:

public class MyJobBackgroundService : BackgroundService
{
    private readonly ILogger<MyJobBackgroundService> _logger;
    private readonly JobQueue<MyJob> _queue;

    public MyJobBackgroundService(ILogger<MyJobBackgroundService> logger, JobQueue<MyJob> queue)
    {
        _logger = logger;
        _queue = queue;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var job = await _queue.DequeueAsync(stoppingToken);

            // do stuff
            _logger.LogInformation("Working on job {JobId}", job.Id);
            await Task.Delay(2000);
        }
    }
}

In a controller action or a Razor page model, you then just need to inject the JobQueue<MyJob> and then call Enqueue on it to add a job to the list.在控制器操作或 Razor 页面模型中,您只需要注入JobQueue<MyJob> ,然后对其调用Enqueue即可将作业添加到列表中。 Once the background service is ready to process it, it will then work on it.一旦后台服务准备好处理它,它就会处理它。

Finally note that the queue is obviously in-memory, so if your application shuts down, the list of yet-to-do jobs is also gone.最后请注意,队列显然在内存中,因此如果您的应用程序关闭,尚未完成的作业列表也将消失。 If you need, you could also persist this information within a database of course and set up the queue from the database.如果需要,当然也可以将此信息保存在数据库中,并从数据库设置队列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM