.Net Core 队列后台任务 [英] .Net Core Queue Background Tasks

查看:61
本文介绍了.Net Core 队列后台任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Slender 回答了我最初的问题,即在发送 HTTP 响应后会发生什么情况,但现在我留下了如何正确排队后台任务的问题

Slender answered my original question about what happens to fire and forget, after the HTTP Response is sent, but Now I'm left with the question how to properly queue background tasks

编辑

众所周知,Async void 通常是不好的,除了在涉及事件处理程序的情况下,我想要执行一些后台逻辑而不必让客户端等待.我最初的想法是使用 Fire and Forget

As we all know Async void is generally bad, except for in the case when it comes to event handlers, I would like to execute some background logic without have to have the client wait. My original Idea was to use Fire and Forget

假设我有一个活动:

public event EventHandler LongRunningTask;

然后有人订阅了一个不用管的任务:

And then someone subscribes a fire and forget task:

LongRunningTask += async(s, e) => { await LongNetworkOperation;};

web api 方法是调用:

the web api method is call:

[HttpGet]
public async IActionResult GetTask()
{
    LongRunningTask?.Invoke(this, EventArgs.Empty);
    return Ok();
}

但是如果我这样做我的长时间运行的任务不能保证完成,我如何处理正在运行的后台任务而不影响我提出请求所需的时间(例如我不想等待任务先完成)?

But If I do this my long running task isn't guaranteed to finish, How can I handle running background task without affect the time the time it take to make my request (e.g I don't want to wait for the task to finish first)?

推荐答案

.NET Core 2.1 有一个 IHostedService,它将在后台安全地运行任务.我在 QueuedHostedService 的 >documentation,我已将其修改为使用 BackgroundService.

.NET Core 2.1 has an IHostedService, which will safely run tasks in the background. I've found an example in the documentation for QueuedHostedService which I've modified to use the BackgroundService.

public class QueuedHostedService : BackgroundService
{
   
    private Task _backgroundTask;
    private readonly ILogger _logger;

    public QueuedHostedService(IBackgroundTaskQueue taskQueue, ILoggerFactory loggerFactory)
    {
        TaskQueue = taskQueue;
        _logger = loggerFactory.CreateLogger<QueuedHostedService>();
    }

    public IBackgroundTaskQueue TaskQueue { get; }

    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (false == stoppingToken.IsCancellationRequested)
        {
            var workItem = await TaskQueue.DequeueAsync(stoppingToken);
            try
            {
                await workItem(stoppingToken);
            }
            catch (Exception ex)
            {
                this._logger.LogError(ex, $"Error occurred executing {nameof(workItem)}.");
            }
        }
    }
}

public interface IBackgroundTaskQueue
{
    void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem);

    Task<Func<CancellationToken, Task>> DequeueAsync(
        CancellationToken cancellationToken);
}

public class BackgroundTaskQueue : IBackgroundTaskQueue
{
    private ConcurrentQueue<Func<CancellationToken, Task>> _workItems =
        new ConcurrentQueue<Func<CancellationToken, Task>>();

    private SemaphoreSlim _signal = new SemaphoreSlim(0);

    public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
    {
        if (workItem == null)
        {
            throw new ArgumentNullException(nameof(workItem));
        }

        _workItems.Enqueue(workItem);
        _signal.Release();
    }

    public async Task<Func<CancellationToken, Task>> DequeueAsync( CancellationToken cancellationToken)
    {
        await _signal.WaitAsync(cancellationToken);
        _workItems.TryDequeue(out var workItem);

        return workItem;
    }
}

现在我们可以安全地在后台对任务进行排队,而不会影响响应请求所需的时间.

Now we can safely queue up tasks in the background without affecting the time it takes to respond to a request.

这篇关于.Net Core 队列后台任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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