.net core 基于 IHostedService 实现定时任务

640?wx_fmt=png

.net core 基于 IHostedService 实现定时任务

Intro

从 .net core 2.0 开始,开始引入 IHostedService,可以通过 IHostedService 来实现后台任务,但是只能在 WebHost 的基础上使用。从 .net core 2.1 开始微软引入通用主机( GenericHost),使得我们可以在不使用 Web 的情况下,也可以使用 IHostedService 来实现 定时任务/Windows服务/后台任务,并且引入了一个 BackgroundService 抽象类来更方便的创建后台任务。

IHostedService

IHostedService 后台任务的执行与应用程序(就此而言,为主机或微服务)的生存期相协调。当应用程序启动时注册任务,当应用程序关闭时,有机会执行某些正常操作或清理。

始终可以启动后台线程来运行任何任务,而无需使用 IHostedService。不同之处就在于应用的关闭时间,此时会直接终止线程,而没有机会执行正常的清理操作。

当注册 IHostedService 时,.NET Core 会在应用程序启动和停止期间分别调用 IHostedService 类型的 StartAsync()StopAsync() 方法。具体而言,即在服务器已启动并已触发 IApplicationLifetime.ApplicationStarted 后调用 start。

  1. namespace Microsoft.Extensions.Hosting

  2. {

  3. //

  4. // Summary:

  5. // Defines methods for objects that are managed by the host.

  6. public interface IHostedService

  7. {

  8. //

  9. // Summary:

  10. // Triggered when the application host is ready to start the service.

  11. Task StartAsync(CancellationToken cancellationToken);

  12. //

  13. // Summary:

  14. // Triggered when the application host is performing a graceful shutdown.

  15. Task StopAsync(CancellationToken cancellationToken);

  16. }

  17. }

可以从头开始创建自定义托管服务类并实现 IHostedService,因为在使用 .NET Core 2.0 时需执行这些操作。

但是,由于大多数后台任务在取消令牌管理和其他典型操作方面都有类似的需求,因此 .net core 2.1 有一个非常方便且可以从中进行派生的抽象基类, BackgroundService 定义如下:

  1. // Copyright (c) .NET Foundation. Licensed under the Apache License, Version 2.0.

  2. /// <summary>

  3. /// Base class for implementing a long running <see cref="IHostedService"/>.

  4. /// </summary>

  5. public abstract class BackgroundService : IHostedService, IDisposable

  6. {

  7. private Task _executingTask;

  8. private readonly CancellationTokenSource _stoppingCts =

  9. new CancellationTokenSource();


  10. protected abstract Task ExecuteAsync(CancellationToken stoppingToken);


  11. public virtual Task StartAsync(CancellationToken cancellationToken)

  12. {

  13. // Store the task we're executing

  14. _executingTask = ExecuteAsync(_stoppingCts.Token);


  15. // If the task is completed then return it,

  16. // this will bubble cancellation and failure to the caller

  17. if (_executingTask.IsCompleted)

  18. {

  19. return _executingTask;

  20. }


  21. // Otherwise it's running

  22. return Task.CompletedTask;

  23. }


  24. public virtual async Task StopAsync(CancellationToken cancellationToken)

  25. {

  26. // Stop called without start

  27. if (_executingTask == null)

  28. {

  29. return;

  30. }


  31. try

  32. {

  33. // Signal cancellation to the executing method

  34. _stoppingCts.Cancel();

  35. }

  36. finally

  37. {

  38. // Wait until the task completes or the stop token triggers

  39. await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));

  40. }


  41. }


  42. public virtual void Dispose()

  43. {

  44. _stoppingCts.Cancel();

  45. }

  46. }

640?wx_fmt=png

实现一个简单的后台定时任务

基于上面的信息,我们可以基于 IHostedService 实现一个简单的后台定时任务服务,

  1. public abstract class ScheduedService : IHostedService, IDisposable

  2. {

  3. private readonly Timer _timer;

  4. private readonly TimeSpan _period;

  5. protected readonly ILogger Logger;


  6. protected ScheduedService(TimeSpan period, ILogger logger)

  7. {

  8. Logger = logger;

  9. _period = period;

  10. _timer = new Timer(Execute, null, Timeout.Infinite, 0);

  11. }


  12. public void Execute(object state = null)

  13. {

  14. try

  15. {

  16. Logger.LogInformation("Begin execute service");

  17. ExecuteAsync().Wait();

  18. }

  19. catch (Exception ex)

  20. {

  21. Logger.LogError(ex, "Execute exception");

  22. }

  23. finally

  24. {

  25. Logger.LogInformation("Execute finished");

  26. }

  27. }


  28. protected abstract Task ExecuteAsync();


  29. public virtual void Dispose()

  30. {

  31. _timer?.Dispose();

  32. }


  33. public Task StartAsync(CancellationToken cancellationToken)

  34. {

  35. Logger.LogInformation("Service is starting.");

  36. _timer.Change(TimeSpan.FromSeconds(SecurityHelper.Random.Next(10)), _period);

  37. return Task.CompletedTask;

  38. }


  39. public Task StopAsync(CancellationToken cancellationToken)

  40. {

  41. Logger.LogInformation("Service is stopping.");


  42. _timer?.Change(Timeout.Infinite, 0);


  43. return Task.CompletedTask;

  44. }

  45. }

基于上面这个基于Timer实现的后台定时任务类实现一个定时任务:

  1. public class RemoveOverduedReservtaionService : ScheduedService

  2. {

  3. public RemoveOverduedReservtaionService(ILogger<RemoveOverduedReservtaionService> logger) : base(TimeSpan.FromDays(1), logger)

  4. { }


  5. protected override Task ExecuteAsync()

  6. {

  7. return DependencyResolver.Current.TryInvokeServiceAsync<IEFRepository<ReservationDbContext, Reservation>>(reservationRepo =>

  8. {

  9. return reservationRepo.DeleteAsync(reservation => reservation.ReservationStatus == 0 && (reservation.ReservationForDate < DateTime.Today.AddDays(-3)));

  10. });

  11. }

  12. }

这个类实现的是每天执行一次,删除三天前状态为待审核的预约,完整实现代码:https://github.com/WeihanLi/ActivityReservation/blob/dev/ActivityReservation.Helper/Services/RemoveOverduedReservtaionService.cs

执行日志:

640?wx_fmt=png

通过日志可以看到我们的定时任务确实是每天执行一次,这样我们的定时任务就算是简单的完成了。

Reference

  • https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services

  • https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice

  • https://docs.microsoft.com/zh-cn/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice

  • https://www.stevejgordon.co.uk/asp-net-core-2-ihostedservice

  • https://github.com/WeihanLi/ActivityReservation


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314669.shtml

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

相关文章

nowcoder 清楚姐姐的翅膀们 F 一般图的最大匹配

传送门 文章目录题意思路&#xff1a;题意 思路&#xff1a; 这个题很容易就会掉到二分图匹配的坑里。。 但实际上这个是一个一般图匹配。 考虑将妹子拆点&#xff0c;一个入点一个出点&#xff0c;入点出点都连蝴蝶结。 我们看看最终会有三种匹配情况&#xff1a; (1)(1)(1)妹…

HDU - 7072 Boring data structure problem 双端队列 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 你需要实现如下四个操作 q≤1e7q\le1e7q≤1e7 思路&#xff1a; 做的时候想了个链表的思路让队友写了&#xff0c;懒。 看了题解感觉题解还是很妙的。 你需要快速插入一个数在前后两端&#xff0c;还需要…

C#中谁最快:结构还是类?

前言在内存当道的日子里&#xff0c;无论什么时候都要考虑这些代码是否会影响程序性能呢&#xff1f;在现在的世界里&#xff0c;几乎不会去考虑用了几百毫秒&#xff0c;可是在特别的场景了&#xff0c;往往这几百毫米确影响了整个项目的快慢。通过了解这两者之间的性能差异&a…

阅读nopcommerce startup源码

创建一个asp.net core项目&#xff0c;可以到到startup类有两个方法// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services)public void Configure(IApplicationBuilder a…

HDU - 7073 Integers Have Friends 2.0 随机化 + 质因子

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个序列aaa&#xff0c;找一个最大的集合&#xff0c;集合中所有元素模mmm相等。 思路&#xff1a; 之前做过一道连续的&#xff0c;直接尺取就好&#xff0c;这个不连续加大了难度。 考虑最简单的…

一份关于.NET Core云原生采用情况调查

调查背景Kubernetes 越来越多地在生产环境中使用&#xff0c;围绕 Kubernetes 的整个生态系统在不断演进&#xff0c;新的工具和解决方案也在持续发布。云原生计算的发展驱动着各个企业转向遵循云原生原则&#xff08;启动速度快、内存占用低&#xff09;的平台&#xff0c; .N…

KPI在小型产品团队中的实践

最近公司决定对所有技术人员实行KPI考核&#xff0c;曾经一度非常反感KPI的我也被要求制定产品团队的KPI指标。为什么要实行KPI考核&#xff0c;因为在项目团队和产品团队的管理中出现了问题&#xff1a;不同项目团队的开发人员的工作量饱和度问题&#xff0c;阶段性会出现有的…

历久弥新 - 微软万亿市值背后的文化支撑(上)|DevOps案例研究

内容来源&#xff1a;DevOps案例深度研究-Microsoft文化支撑研究战队&#xff08;本文只展示部分PPT研究成果&#xff0c;更多细节请关注案例分享会&#xff0c;及本公众号。&#xff09;本案例内容贡献者&#xff1a;陈飞&#xff08;Topic Leader&#xff09;、陈雨卿、郭子奇…

ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建

在上一个小系列文章《ASP.NET Core on K8S学习初探》中&#xff0c;通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境&#xff0c;并初步尝试将ASP.NET Core WebAPI项目部署到了K8S&#xff0c;把玩了一下快速部署和实例伸缩。这个系列开始&#xff0c;会继续学…

我眼中的 NCC,WTM 寻亲之旅

峥嵘岁月如谢花流水&#xff0c;三朝五帝如散雾云海。开发语言更迭如此。我们所坚持的&#xff0c;只是那最初的感动&#xff0c;那“只是在人群中多看了你一眼”的惊艳。三十年河东&#xff0c;三十年河西&#xff0c;不忘初心&#xff0c;方得始终&#xff01;嗯&#xff0c;…

Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory 思维 + dp

文章目录题意&#xff1a;思路题意&#xff1a; 思路 一开始找规律&#xff0c;表都打好了&#xff0c;没找出来。。 找规律还是适合让队友来。 先考虑第一行&#xff0c;我们先计算第一行的方案数&#xff0c;设f[i][j]f[i][j]f[i][j]表示到了iii位&#xff0c;第iii位的颜色…

Wtm携手LayUI -- .netcore 开源生态我们是认真的!

经过WTM团队和LayUI团队多次深入协商&#xff0c;双方于2019年7月29日在北京中国国际展览中心正式达成战略合作意向&#xff0c;双方签署了战略合作框架协议&#xff0c;LayUI团队承诺使用WTM框架的任何项目都可以免费使用其收费版的后台模板&#xff0c;WTM团队则从受捐助款项…

Codeforces Round #305 (Div. 1) D. Mike and Fish 欧拉回路

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 欧拉回路经典题。 将其转换成图上问题&#xff0c;对于横纵坐标我们将其分开&#xff0c;对于(x,y)(x,y)(x,y)我们将其横纵坐标连一个无向边&#xff0c;现在问题就转换成了我们需要对每条…

高性能动态编译库Natasha发布1.0版本!

一、 前言对于开源贡献者&#xff0c;Emit和表达式树不是陌生的字眼&#xff0c;IL的动态特性为封装工作带来了极大的方便&#xff0c;会Emit的开发者可以说驾驭了大部分的高性能、高动态的编程技巧。纵观ef、dapper、json.net等第三方常用库&#xff0c;哪个能脱离emit而独善其…

Codeforces Round #245 (Div. 1) E. Points and Segments 欧拉回路 + 建模

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 考虑对于线段&#xff0c;如何建模。 我们考虑先将线段转换成左闭右开的形式&#xff0c;将左右点连起来。 再考虑每个点&#xff0c;将所有离散化后的点拿出来&#xff0c;每个点都有一个…

微软.Net Core 3.0 预览版7发布:大幅减少 SDK 空间大小

据悉&#xff0c;这个预览版是 .Net Core 3 中重要的版本&#xff0c;可以视为原计划在 7 月发布的 RC 版本 (引自微软 .NET Core 首席 Program Manager Richard 先生原话&#xff09;&#xff0c;故可在生产环境进行开发和部署。Windows, macOS 和 Linux 版本的Download .NET …

5门可能衰落的编程语言

专注于为北美地区的科技专业人士提供行业见解和分析&#xff0c;以及提供求职消息的技术职业消息服务网站 Dice Insights 近日发表了一篇题为《5 Programming Languages That Are Probably Doomed》的文章。作者主要根据 TIOBE 和 RedMonk 这两个编程语言排行榜&#xff0c;以及…

.NET加水印/验证码的NuGet包

.NET加水印/验证码的NuGet包 我的在前两篇文章中&#xff0c;我介绍了使用Direct2D给图片加水印/验证码&#xff0c;今天我将其进行了封装&#xff0c;发布了一个NuGet包Sdcb.Imaging&#xff1a;<PackageReference Include"Sdcb.Imaging" Version"1.1.0&quo…

hdu1686:KMP板子

题目链接 题目大意就是给你两个字符串&#xff0c;求出第一个字符串在第二个字符串中出现的次数。 如果我们暴力匹配的话&#xff0c;复杂度是 len(first) * len(second) 对于题目给的 1e4 * 1e6 显然暴力不可取&#xff0c; 这里就用到 KMP 。 说到 KMP 最难理解的就是 next…

集群故障处理之处理思路以及健康状态检查(三十三)

前言 按照笔者的教程&#xff0c;大家应该都能够比较顺畅的完成k8s集群的部署&#xff0c;不过由于环境、配置以及对Linux、k8s的不了解会导致很多问题、异常和故障&#xff0c;这里笔者分享一些处理技巧和思路&#xff0c;以及部分常见的问题&#xff0c;以供大…