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

 最近,有一个项目要使用 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);//}//如果服务被停止,那么下面的IsCancellationRequested会返回true,我们就应该结束循环while (!stoppingToken.IsCancellationRequested){await Task.Delay(_crontab.GetSleepTimeSpan(DateTime.Now), stoppingToken);await Task.Run(() =>{_logger.LogInformation("RunTaskOne running at: {time}", DateTimeOffset.Now);}, stoppingToken); }}/// <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);//}//如果服务被停止,那么下面的IsCancellationRequested会返回true,我们就应该结束循环while (!stoppingToken.IsCancellationRequested){await Task.Delay(_crontab.GetSleepTimeSpan(DateTime.Now), stoppingToken);await Task.Run(() =>{_logger.LogInformation("RunTaskTwo running at: {time}", DateTimeOffset.Now);}, stoppingToken);}}/// <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);//}//如果服务被停止,那么下面的IsCancellationRequested会返回true,我们就应该结束循环while (!stoppingToken.IsCancellationRequested){await Task.Delay(_crontab.GetSleepTimeSpan(DateTime.Now), stoppingToken);await Task.Run(() =>{_logger.LogInformation("RunTaskThree running at: {time}", DateTimeOffset.Now);}, stoppingToken);}}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.CompletedTask;// 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.rhkb.cn/news/148227.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go 代码中的文档和注释

撰写清晰、简洁和全面的代码文档的指南 在软件开发领域&#xff0c;编写代码只占了一半的战斗。另一半则围绕着创建清晰、简洁和全面的文档展开&#xff0c;这些文档不仅有助于开发人员理解代码库&#xff0c;还充当未来开发的路线图。在本指南中&#xff0c;我们将深入探讨编…

Spring:通过@Lazy解决构造方法形式的循环依赖问题

一、定义2个循环依赖的类 package cn.edu.tju.domain2;import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component;Component public class A {private final B b;public B getB() {return b;}Lazypublic A(B b){this.b b;//Sy…

[React源码解析] React的设计理念和源码架构 (一)

任务分割异步执行让出执法权 文章目录 1.React的设计理念1.1 Fiber1.2 Scheduler1.3 Lane1.4 代数效应 2.React的源码架构2.1 大概图示2.2 jsx2.3 Fiber双缓存2.4 scheduler2.5 Lane模型2.6 reconciler2.7 renderer2.8 concurrent 3.React源码调试 1.React的设计理念 Fiber: 即…

python获取时间戳

使用 datetime 库获取时间。 获取当前时间&#xff1a; import datetime print(datetime.datetime.now()) . 后面的是微秒&#xff0c;也是一个时间单位&#xff0c;1秒1000000微秒。 转为时间戳&#xff1a; import datetimedate datetime.datetime.now() timestamp date…

最短路径专题5 最短路径

题目&#xff1a; 样例&#xff1a; 输入 4 5 0 2 0 1 2 0 2 5 0 3 1 1 2 2 3 2 2 输出 3 0->3->2 思路&#xff1a; 根据题目意思&#xff0c;求最短路&#xff0c;这个根据平时的Dijkstra&#xff08;堆优化&#xff09;即可&#xff0c;关键在于求路径的方法&#x…

uni-app:实现页面效果2(canvas绘制,根据页面宽度调整元素位置)

效果 代码 <template><view><!-- 车搭配指示器-双显 --><view class"content_position"><view class"content"><view class"SN"><view class"SN_title">设备1</view><view class…

视频讲解|含可再生能源的热电联供型微网经济运行优化(含确定性和源荷随机两部分代码)

1 主要内容 该视频为《含可再生能源的热电联供型微网经济运行优化》代码讲解内容&#xff0c;对应的资源下载链接为考虑源荷不确定性的热电联供微网优化-王锐matlab&#xff08;含视频讲解&#xff09;&#xff0c;对该程序进行了详尽的讲解&#xff0c;基本做到句句分析和讲解…

源码系列 之 ThreadLocal

简介 ThreadLocal的作用是做数据隔离&#xff0c;存储的变量只属于当前线程&#xff0c;相当于当前线程的局部变量&#xff0c;多线程环境下&#xff0c;不会被别的线程访问与修改。常用于存储线程私有成员变量、上下文&#xff0c;和用于同一线程&#xff0c;不同层级方法间传…

【数据结构】链表与LinkedList

作者主页&#xff1a;paper jie 的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVA数据结构》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精…

Ubuntu中启动HDFS后没有NameNode解决办法

关闭进程&#xff1a; stop-dfs.sh 格式化&#xff1a; hadoop namenode -format 出现报错信息&#xff1a; 23/10/03 22:27:04 WARN fs.FileUtil: Failed to delete file or dir [/usr/data/hadoop/tmp/dfs/name/current/fsimage_0000000000000000000.md5]: it still exi…

3种等待方式,让你学会Selenium设置自动化等待测试脚本!

一、Selenium脚本为什么要设置等待方式&#xff1f;——即他的应用背景到底是什么 应用Selenium时&#xff0c;浏览器加载过程中无法立即显示对应的页面元素从而无法进行元素操作&#xff0c;需设置一定的等待时间去等待元素的出现。&#xff08;简单来说&#xff0c;就是设置…

黑马mysql教程笔记(mysql8教程)基础篇——数据库相关概念、mysql安装及卸载、数据模型、SQL通用语法及分类(DDL、DML、DQL、DCL)

参考文章1&#xff1a;https://www.bilibili.com/video/BV1Kr4y1i7ru/ 参考文章2&#xff1a;https://dhc.pythonanywhere.com/article/public/1/ 文章目录 基础篇数据库相关概念&#xff08;数据库DataBase&#xff08;DB&#xff09;、数据库管理系统DataBase Management Sy…

正则表达式基本使用

文章目录 1. 基本介绍2. 元字符(Metacharacter)-转义号 \\3. 元字符-字符匹配符3.1 案例 4. 元字符-选择匹配符5. 元字符-限定符6. 元字符-定位符7. 分组7.1 捕获分组7.2 非捕获分组 8. 非贪婪匹配9. 应用实例10. 正则验证复杂URL 1. 基本介绍 如果要想灵活的运用正则表达式&a…

【算法学习】-【双指针】-【快乐数】

LeetCode原题链接&#xff1a;202. 快乐数 下面是题目描述&#xff1a; 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。 如果…

Linux:minishell

目录 1.实现逻辑 2.代码及效果展示 1.打印字符串提示用户输入指令 2.父进程拆解指令 3.子进程执行指令,父进程等待结果 4.效果 3.实现过程中遇到的问题 1.打印字符串的时候不显示 2.多换了一行 3.cd路径无效 4.优化 1.ll指令 2.给文件或目录加上颜色 代码链接 模…

Redis相关概念

1. 什么是Redis&#xff1f;它主要用来什么的&#xff1f; Redis&#xff0c;英文全称是Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提…

IDT 一款自动化挖掘未授权访问漏洞的信息收集工具

IDT v1.0 IDT 意为 Interface detection&#xff08;接口探测) 项目地址: https://github.com/cikeroot/IDT/该工具主要的功能是对批量url或者接口进行存活探测&#xff0c;支持浏览器自动打开指定的url&#xff0c;避免手动重复打开网址。只需输入存在批量的url文件即可。 …

SpringBoot快速入门

搭建SpringBoot工程&#xff0c;定义hello方法&#xff0c;返回“Hello SpringBoot” ②导入springboot工程需要继承的父工程&#xff1b;以及web开发的起步依赖。 ③编写Controller ④引导类就是SpringBoot项目的一个入口。 写注解写main方法调用run方法 快速构建SpringBoo…

动态规划-状态机(188. 买卖股票的最佳时机 IV)

状态分类&#xff1a; f[i,j,0]考虑前i只股票&#xff0c;进行了j笔交易&#xff0c;目前未持有股票 所能获得最大利润 f[i,j,1]考虑前i只股票&#xff0c;进行了j笔交易&#xff0c;目前持有股票 所能获得最大利润 状态转移&#xff1a; f[i][j][0] Math.max(f[i-1][j][0],f[…

DevExpress WinForms图表组件 - 直观的数据信息呈现方式!(二)

在上文中&#xff08;点击这里回顾>>&#xff09;&#xff0c;我们为大家介绍了DevExpress WinForms图表控件的互动图表、图标设计器及可定制功能等&#xff0c;本文将继续介绍DevExpress WinForms图表控件的数据分析、大数据功能等&#xff0c;欢迎持续关注我们哦~ Dev…