.Net Core后台任务启停(BackgroundService)

记 .Net Core后台任务 趟过的坑

oh no,有毒

说到定时任务,可能第一个会想到Quartz,但是想到需要更简洁,而且想要毫秒级的周期,这个Cron真是太不智慧了,虽说可以在单个任务中轮询,但是这个Trigger用起来是很不适应。那么找找源头,有什么简单的方法开启定时任务,然后大佬是这样说的 帮助
在这里插入图片描述
看起来很不错啊,只需要简单继承 BackgroundService 基类就可以了,先来做个测试,重写一下开始、结束、执行:
在这里插入图片描述
运行一下试试,很不错,看起来如此的简单。
在这里插入图片描述
但是为什么 停止不了!停止不了!停止不了!,只能求助网上各位大佬了,在此感谢
osc_aq3v6w0z的帮助 原文链接

BackgroundService 中函数调用 ExecuteAsync 时给它赋的参数直接是一个内部的只读变量,你在外部调用,StartAsync 给它输入的参数根本就没有用到。

到底怎么回事

说到是BackgroundService 基类中并没有使用传进去的参数,那么来看看源码长什么样(开源福利)

// Copyright (c) .NET Foundation. Licensed under the Apache License, Version 2.0.
/// <summary>
/// Base class for implementing a long running <see cref="IHostedService"/>.
/// </summary>
public abstract class BackgroundService : IHostedService, IDisposable
{
    private Task _executingTask;
    private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();

    protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

    public virtual Task StartAsync(CancellationToken cancellationToken)
    {
        // Store the task we're executing
        _executingTask = ExecuteAsync(_stoppingCts.Token);

        // If the task is completed then return it,
        // this will bubble cancellation and failure to the caller
        if (_executingTask.IsCompleted)
        {
            return _executingTask;
        }
        // Otherwise it's running
        return Task.CompletedTask;
    }

    public virtual async Task StopAsync(CancellationToken cancellationToken)
    {
        // Stop called without start
        if (_executingTask == null)
        {
            return;
        }
        try
        {
            // Signal cancellation to the executing method
            _stoppingCts.Cancel();
        }
        finally
        {
            // Wait until the task completes or the stop token triggers
            await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite,cancellationToken));
        }

    }

    public virtual void Dispose()
    {
        _stoppingCts.Cancel();
    }
}

确实,这就是问题的根源,那么看看怎么办

方法一:跳过StartAsync、StopAsync ,直接调用 ExecuteAsync ;
方法二:仿照官方的 BackgroundService,实现 IHostedService 接口,自己写一个BackgroundService
方法三:使用 BackgroundWorker

下面来尝试一下方法二,简单的件token替换一下
在这里插入图片描述
running…
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值