在业务场景中经常需要后台服务不停的或定时处理一些任务,这些任务是不需要及时响应请求的。

在 asp.net中会使用windows服务来处理。

在 asp.net core中,可以使用托管服务来实现,托管服务是一个类,具有实现IHostService接口的后台任务逻辑。

导入包

使用NUGET添加Microsoft.Extensions.Hosting包到项目中

 Microsoft.Extensions.Hosting包地址

IHostedService接口

  • 托管服务必须实现IHostedService接口,该接口为主机管理的对象定义了两种方法。

    StartAsync(CancellationToken) - StartAsync包含启动后台任务的逻辑。使用Web主机时,StartAsync在服务器启动并且触发IApplicationLifetime.ApplicationStarted后调用。使用Generic Host时,StartAsync会在ApplicationStarted触发之前调用。

  • StopAsync(CancellationToken) - 在主机执行正常关闭时触发。StopAsync包含结束后台任务的逻辑。实现IDisposable和终结器(析构函数)来处理任何非托管资源。

取消令牌具有默认的五秒超时,以指示关闭过程不再是正常的。在令牌上请求取消时:

应该中止应用正在执行的任何剩余后台操作。

任何调用的方法都StopAsync应该立即返回。

但是,在请求取消后,任务不会被放弃 - 调用者等待所有任务完成。

如果应用程序被意外关闭(例如,应用程序的进程失败),则StopAsync可能无法调用。因此,StopAsync是有可能不会被调用的。

托管服务在应用启动时激活一次,并在应用关闭时正常关闭。为防止异常,最好继承IDispose接口,释放资源

定时后台任务用例

可以写一个托管服务类直接继承IHostedService,和IDisposable接口

 public class MyTimerHostedService : IHostedService, IDisposable
{
private Timer _timer; public Task StartAsync(CancellationToken cancellationToken)
{
Console.WriteLine("启动定时任务托管服务"); _timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(0.5)); return Task.CompletedTask;
} private void DoWork(object state)
{
Console.WriteLine("定时任务处理中");
} public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, 0);
Console.WriteLine("停止定时任务");
return Task.CompletedTask;
} public void Dispose()
{
// 手动释放定时器
_timer?.Dispose();
}
}

该服务Startup.ConfigureServices使用AddHostedService扩展方法注册:

services.AddHostedService<MyTimerHostedService>();

使用通用主机启动 托管服务

  class Program
{
static void Main(string[] args)
{
var host = new HostBuilder().ConfigureServices((hostContext, services) =>
{
services.AddHostedService<MyTimerHostedService>();
}).Build(); host.Run(); Console.WriteLine("Hello World!");
Console.ReadLine();
}
}

使用后台服务BackgroundService 实现

.NET Core中实现的抽象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();
}
}

由于抽象类已经实现了IHostService接口定义的方法,只需要写子类去继承BackgroundService, 在自己的自定义托管服务类中实现ExecuteAsync()方法

 public class MyBackGroundService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Console.WriteLine("MyBackGroundService doing"); //延迟500毫秒执行 相当于使用了定时器
await Task.Delay(500, stoppingToken);
}
}
}

在主机中托管服务

class Program
{
static void Main(string[] args)
{
var host = new HostBuilder().ConfigureServices((hostContext, services) =>
{
//services.AddHostedService<MyTimerHostedService>();
services.AddHostedService<MyBackGroundService>();
}).Build(); host.Run(); Console.WriteLine("Hello World!");
Console.ReadLine();
}
}

使用了HostService后极大的方便了后台任务的管理

github源码地址

在asp.net core中使用托管服务实现后台任务的更多相关文章

  1. 第二十二节:Asp.Net Core中使用托管服务实现后台任务

    1. 说明 BackgroundService 是用于实现长时间运行的 IHostedService 的基类,使用程序集:Microsoft.Extensions.Hosting. 2. 实现方式 继 ...

  2. 在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度

    在这篇文章中,我将介绍如何使用ASP.NET Core托管服务运行Quartz.NET作业.这样的好处是我们可以在应用程序启动和停止时很方便的来控制我们的Job的运行状态.接下来我将演示如何创建一个简 ...

  3. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  4. Asp.net Core中使用Session

    前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...

  5. 在ASP.NET Core中使用百度在线编辑器UEditor

    在ASP.NET Core中使用百度在线编辑器UEditor 0x00 起因 最近需要一个在线编辑器,之前听人说过百度的UEditor不错,去官网下了一个.不过服务端只有ASP.NET版的,如果是为了 ...

  6. ASP.NET Core中的依赖注入(1):控制反转(IoC)

    ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...

  7. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  8. ASP.NET Core中的依赖注入(3): 服务的注册与提供

    在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core ...

  9. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

随机推荐

  1. IDEA+maven搭建scala开发环境(spark)(半转载)

    以下内容部分来自于https://zhuanlan.zhihu.com/p/23141509,我尝试了一遍,然后添加了一些图片.. 其实我觉得在IDEA中使用scala插件然后创建project的时候 ...

  2. (三十一)c#Winform自定义控件-文本框(四)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  3. gcd 和 同余方程(Exgcd)

    求关于x的同余方程 ax≡1(mod b) 的最小正整数解. 对于 100%的数据,2≤a,b≤2*109. NOIP 2012 提高组 第二天 第一题 (只看Exgcd的自行跳过这段文字) 先撇开扩 ...

  4. 关于阿里云Mysql分页查询不走索引的问题

    需要修改阿里云中的MYSQL 配置参数 : eq_range_index_dive_limit 阿里云上默认是 10 , 这个参数 表示 in 查询 条件超过 10 个 就不走索引,走全表扫描.如果我 ...

  5. Kali Linux无法访问网络的问题

    首先 ping www.baidu.com ping: unkown host www.baidu.com 然后 ping 8.8.8.8 connect:network is unreachable ...

  6. 测试常用的sql语句

    1.查询:select * from table_name where 条件语句; SELECT * from sms_runwater WHERE message LIKE "%自有支付% ...

  7. 蔡勒(Zeller)公式及其推导:快速将任意日期转换为星期数

    0. 本文的初衷及蔡勒公式的用处 前一段时间,我在准备北邮计算机考研复试的时候,做了几道与日期计算相关的题目,在这个过程中我接触到了蔡勒公式.先简单的介绍一下蔡勒公式是干什么用的. 我们有时候会遇到这 ...

  8. DC-2靶机渗透

    靶场下载链接: Download: http://www.five86.com/downloads/DC-2.zip Download (Mirror): https://download.vulnh ...

  9. 第一章 .NET基础-C#基础

    一.1.1. 基础语法 一.1.1.1. 注释符 一.1.1.1.1. 注释符的作用 l 注释 l 解释 一.1.1.1.2. C#中的3中注释符 l 单行注释 // l 多上注释 /* 要注释的内容 ...

  10. Mybatis框架(9)---Mybatis自定义插件生成雪花ID做为表主键项目

    Mybatis自定义插件生成雪花ID做为主键项目 先附上项目项目GitHub地址 spring-boot-mybatis-interceptor 有关Mybatis雪花ID主键插件前面写了两篇博客作为 ...