.netcore worker service在一个worker里执行多个任务的方法

news/2024/5/20 0:33:45 标签: .netcore

 最近,有一个项目要使用 Windows 服务,来做为一个软件项目的载体。我想了想,都已经到了跨平台的时代了,会不会有替换 Windows 服务的技术出现呢?于是,在网络上疯狂的搜索了一番,真实皇天不负苦心人,找到了一个答案,那就是 Worker Service。听说在 NET Core 3.0 的时代就新增了 Worker Service 的新项目模板,可以编写长时间运行的后台服务,并且能轻松的部署成 windows 服务或 linux 守护程序。如果安装的 vs2022 是中文版本,Worker Service 的项目名称就变成了辅助角色服务。 

关于Worker类,既可以写多个,比如 WorkerOne,WorkerTwo 来实现多个任务,也可以在一个Worker类里实现多任务,前者的demo代码如下:

using Furion.TimeCrontab;

namespace WorkerServiceTest
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        
        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        //重写BackgroundService.StartAsync方法,在开始服务的时候,执行一些处理逻辑,这里我们仅输出一条日志
        public override async Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Worker starting at: {time}", DateTimeOffset.Now);

            await base.StartAsync(cancellationToken);
        }




        /// <summary>
        /// 第一个 windows服务或linux守护程序 的处理逻辑,由RunTaskOne方法内部启动的Task任务线程进行处理,
        /// 同样可以从参数CancellationToken stoppingToken中的IsCancellationRequested属性,得知Worker Service服务是否已经被停止
        /// </summary>
        /// <param name="stoppingToken"></param>
        /// <returns></returns>
        protected async Task RunTaskOne(CancellationToken stoppingToken)
        {
              var _crontab = Crontab.SecondlyAt(1, 10, 20); // 每秒

            //如果服务被停止,那么下面的IsCancellationRequested会返回true,我们就应该结束循环
            while (!stoppingToken.IsCancellationRequested)
            {
                await Task.Delay(_crontab.GetSleepTimeSpan(DateTime.Now), stoppingToken);

                _logger.LogInformation("RunTaskOne running at: {time}", DateTimeOffset.Now);
               // Thread.Sleep(1000);
            }

        }

        /// <summary>
        /// 第二个 windows服务或linux守护程序 的处理逻辑,由RunTaskTwo方法内部启动的Task任务线程进行处理,
        /// 同样可以从参数CancellationToken stoppingToken中的IsCancellationRequested属性,得知Worker Service服务是否已经被停止
        /// </summary>
        /// <param name="stoppingToken"></param>
        /// <returns></returns>
        protected async  Task RunTaskTwo(CancellationToken stoppingToken)
        {
            var _crontab = Crontab.SecondlyAt(30, 35, 40); // / 每第 3,5,6 秒

            //如果服务被停止,那么下面的IsCancellationRequested会返回true,我们就应该结束循环
            while (!stoppingToken.IsCancellationRequested)
            {
                await Task.Delay(_crontab.GetSleepTimeSpan(DateTime.Now), stoppingToken);

                _logger.LogInformation("RunTaskTwo running at: {time}", DateTimeOffset.Now);
                // Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 第三个 windows服务或linux守护程序 的处理逻辑,由RunTaskThree方法内部启动的Task任务线程进行处理,
        /// 同样可以从参数CancellationToken stoppingToken中的IsCancellationRequested属性,得知Worker Service服务是否已经被停止
        /// </summary>
        /// <param name="stoppingToken"></param>
        /// <returns></returns>
        protected async  Task RunTaskThree(CancellationToken stoppingToken)
        {
            var _crontab = Crontab.SecondlyAt(45, 50, 55); // / 每第 3,5,6 秒

            //如果服务被停止,那么下面的IsCancellationRequested会返回true,我们就应该结束循环
            while (!stoppingToken.IsCancellationRequested)
            {
                await Task.Delay(_crontab.GetSleepTimeSpan(DateTime.Now), stoppingToken);

                _logger.LogInformation("RunTaskThree running at: {time}", DateTimeOffset.Now);
                // Thread.Sleep(1000);
            }
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            //while (!stoppingToken.IsCancellationRequested)
            //{
            //    _logger.LogInformation("Worker1 正在进行中 : {time}", DateTimeOffset.Now);
            //    await Task.Delay(1000, stoppingToken);
            //}

            try
            {
                 RunTaskOne(stoppingToken);
                 RunTaskTwo(stoppingToken);
                 RunTaskThree(stoppingToken);

               // await Task.WhenAll(taskOne, taskTwo, taskThree);//使用await关键字,异步等待RunTaskOne、RunTaskTwo、RunTaskThree方法返回的三个Task对象完成,这样调用ExecuteAsync方法的线程会立即返回,不会卡在这里被阻塞
            }
            catch (Exception ex)
            {
                //RunTaskOne、RunTaskTwo、RunTaskThree方法中,异常捕获后的处理逻辑,这里我们仅输出一条日志
                _logger.LogError(ex.Message);
            }
            finally
            {
                //Worker Service服务停止后,如果有需要收尾的逻辑,可以写在这里
            }

        }

        //重写BackgroundService.StopAsync方法,在结束服务的时候,执行一些处理逻辑,这里我们仅输出一条日志
        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Worker1 停止了 : {time}", DateTimeOffset.Now);

            await base.StopAsync(cancellationToken);
        }

    }
}

其他方法可以参考:

https://www.cnblogs.com/PatrickLiu/p/15834732.html

25. 辅助角色服务 | Furion

26.2 Cron 表达式 | Furion


http://www.niftyadmin.cn/n/5063632.html

相关文章

Grander因果检验(格兰杰)原理+操作+解释

笔记来源&#xff1a; 1.【传送门】 2.【传送门】 前沿原理介绍 Grander因果检验是一种分析时间序列数据因果关系的方法。 基本思想在于&#xff0c;在控制Y的滞后项 (过去值) 的情况下&#xff0c;如果X的滞后项仍然有助于解释Y的当期值的变动&#xff0c;则认为 X对 Y产生…

基于Java的实验室设备借用登记系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

意大利开源硬件公司【Arduino】完成2200万美元融资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;意大利开源硬件公司【Arduino】今日宣布已完成2200万美元融资。 本轮融资总额已经达到5400万美元&#xff0c;本轮融资由CDP Venture Capital和Anzu Partners共同领投。 Arduino打算利用这笔资金在…

JavaWeb项目:smbms(mysql)

1.准备工作&#xff0c;创建数据库 CREATE DATABASE smbms;USE smbms;CREATE TABLE smbms_address (id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID,contact VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 联系人姓名,addressDesc VARCHAR(50) COLLATE u…

【Kafka专题】Kafka收发消息核心参数详解

目录 前置知识课程内容一、从基础的客户端说起&#xff08;Java代码集成使用&#xff09;1.1 消息发送者源码示例1.2 消息消费者源码示例1.3 客户端使用小总结 *二、从客户端属性来梳理客户端工作机制*2.1 消费者分组消费机制2.2 生产者拦截器机制2.3 消息序列化机制2.4 消息分…

一文拿捏分布式、分布式缓存及其问题解决

1.分布式 1.集中式 传统的计算模型通常是集中式的&#xff0c;所有的计算任务和数据处理都由单一的计算机或服务器完成。然而&#xff0c;随着数据量和计算需求的增加&#xff0c;集中式系统可能会面临性能瓶颈和可靠性问题。 故而引出了分布式↓↓↓↓↓↓↓↓↓↓↓↓↓↓…

trycatch、throw、throws

在Java中,try-catch、throw和throws是用于处理异常的重要关键字和机制,它们的作用如下: try-catch:try-catch 是用于捕获和处理异常的语句块。在try块中放置可能引发异常的代码。如果在try块中的代码引发了异常,控制流会跳转到与异常类型匹配的catch块。在catch块中,可以…

acwing算法基础之基础算法--整数二分算法

目录 1 知识点2 代码模板 1 知识点 有单调性一定可以二分&#xff0c;但在某些情况下&#xff0c;不具有单调性也可以二分。 单调性也可以抽象成某类性质&#xff0c;分界点左边不满足此性质&#xff0c;而右边满足此性质。当然也可以分界点左边满足此性质&#xff0c;而右边不…