如何在ASPNET Core 3.0中启动后台进程? [英] How do you launch a background process in ASPNET Core 3.0?

查看:44
本文介绍了如何在ASPNET Core 3.0中启动后台进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道新的ASPNET Core 3.0堆栈在托管过程方面有许多改进.

I know that the new ASPNET Core 3.0 stack has a number of improvements around hosting processes.

我对能够从Razor PageModel定义和执行后台进程的最佳方法感到好奇吗?意味着我有一些逻辑,需要在后台启动某些东西,然后Razor页面不需要监视它的结果,但是如果这不太难的话,我也希望能够观察到它.

I am curious about the best way to be able to define and execute a background process from a 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.

有人可以给我看一个代码示例或向我指出正确的方向吗?

Can someone show me a code sample or point me in the right direction?

推荐答案

由于这可能是您上一个关于 IHostedService ,我假设您要在能够执行后台任务的ASP.NET Core应用程序中拥有一些后台服务(作为托管服务).现在您想通过控制器或Razor页面操作触发此类任务,并使其在后台执行?

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. And now you want to trigger such a task through a controller or Razor page action and have it executed in the background?

一个常见的模式是拥有一些中央存储,以跟踪后台服务和Web应用程序都可以访问的任务.一种简单的方法是使它成为双方都可以访问的(线程安全的)单例服务.

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. A simple way to do this is to make it a (thread-safe) singleton service that both sides can access.

该文档实际上显示了一个使用 BackgroundTaskQueue 的简单示例,该示例正是该共享服务/状态.但是,如果您有从事某种特定工作的工人,也可以这样实现:

The docs actually show a simple example using a BackgroundTaskQueue which is exactly that shared service/state. 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);
        }
    }
}

在控制器操作或Razor页面模型中,您只需要注入 JobQueue< MyJob> ,然后调用 Enqueue 将作业添加到列表.一旦后台服务准备好处理它,它将在其上工作.

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. 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.

这篇关于如何在ASPNET Core 3.0中启动后台进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆