首页 > 编程语言 >使用FluentScheduler和IIS预加载在asp.net中实现定时任务管理

使用FluentScheduler和IIS预加载在asp.net中实现定时任务管理

时间:2024-02-10 12:00:14浏览次数:44  
标签:asp IIS lock HostingEnvironment 任务 调用 定时 FluentScheduler

FluentScheduler介绍

github地址:https://github.com/fluentscheduler/FluentScheduler

FluentScheduler是一个简单的任务调度框架,使用起来非常方便,这个框架也是我在搜索iis预加载的时候偶然间发现的,立马拿来试用一下,感觉爽呆了,当然还有Quarz.Net之类的其他任务管理框架,不过看配置似乎有点麻烦,反正除了timer我啥也没用过...

之前还花费了很长一段时间自己写了一套定时任务的框架,如今看到FluentScheduler我已经决定将之前的废弃了...

好吧,废话不多说,框架调用非常简单,所以直接上代码了,其实我做的只不过是把英文翻译一下

FluentScheduler使用

.net 框架:.net framework 4.5

项目:.net mvc5

如果要在winform,wpf之类的项目中使用是完全没有问题的,因为本文最终的目标是实现将该web项目作为一个定时任务的服务,所以选择了以上的架构

1.引用nuget包:FluentScheduler

2.Application_Start函数加上:

//初始化任务管理器
JobManager.Initialize(new MyRegistry());

3.MyRegistry.cs

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        // Schedule an IJob to run at an interval
        // 立即执行每10秒一次的计划任务。(指定一个时间间隔运行,根据自己需求,可以是秒、分、时、天、月、年等。)
        Schedule<MyJob>().ToRunNow().AndEvery(10).Seconds();
        // 立即执行每10秒一次的计划任务。如果本次任务没有结束,下一次的任务则不会开始,禁止并行运行
        Schedule<MyJob>().NonReentrant().ToRunNow().AndEvery(10).Seconds();
        //在每天的21:15执行计划任务
        Schedule(() => Console.WriteLine("It's 9:15 PM now.")).ToRunEvery(1).Days().At(21, 15);
        // 立即执行一个在每月的第一个星期一 3:00 的计划任务
        Schedule(() => Console.WriteLine("It's 3:00 AM now.")).ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);
        //在每周一的21:15执行计划任务
        Schedule(() => Console.WriteLine("It's 9:15 PM now.")).ToRunEvery(1).Weeks().On(DayOfWeek.Monday).At(21, 15);
    }

}

上面需要注意的是NonReentrant函数的使用,在某些特殊的业务里可能任务执行的时间比定时循环的间隔时间要长,这时候你就要考虑是否允许并行运行两个同样的任务,NonReentrant就是用来解决这个问题的

4.MyJob.cs

public class MyJob : IJob, IRegisteredObject
{
    private readonly object _lock = new object();

    private bool _shuttingDown;
    private static Logger logger = LogManager.GetCurrentClassLogger(); //初始化日志类
    public MyJob()
    {
        HostingEnvironment.RegisterObject(this);
    }
    public void Execute()
    {
        try
        {
            lock (_lock)
            {
                if (_shuttingDown)
                    return;
                logger.Info("开始工作:" + DateTime.Now);
                Thread.Sleep(60*1000);
                logger.Info("工作结束:" + DateTime.Now);
            }
        }
        finally
        {
            HostingEnvironment.UnregisterObject(this);
        }

    }
    public void Stop(bool immediate)
    {
        logger.Info("调用stop:" + DateTime.Now);
        lock (_lock)
        {
            logger.Info("lock结束:" + DateTime.Now);
            _shuttingDown = true;
        }
        HostingEnvironment.UnregisterObject(this);
    }
}

上面是一个简单的示例,所有的业务逻辑都在Execute函数中执行,如果不在web项目中运行,则不需要实现IRegisteredObject接口以及stop函数,所有的业务代码均在Execute函数中执行

在ASP.NET中作定时任务

在之前我们也有部分项目用widowsservice来做定时任务,但是弊端很明显,调试太麻烦,发布也麻烦,自动发布更难实现

相比之下web服务器就容易管理的多了

实际上在asp.net 中的定时任务和FluentScheduler框架并没有什么必然的联系,你也可以用timer或其他的任何方式来实现,但是所有的这些实现方式都避免不了面对一个问题:IIS的回收机制

因为有了回收机制的存在,所以在asp.net中做定时任务就会面临两个问题:

1.任务没有执行完成线程就被回收了

2.线程回收之后,只有在下一次访问网站的时候任务才会再次启动

首先我们来解决第一个问题:

对于iis的回收,我们需要做的其实并不是阻止它的回收,实际上我试过各种方式都无法完全阻挡iis的回收,不知道是否是方法没有用对。

但是我们可以保证当前的任务执行完毕再进行回收

方式就是实现IRegisteredObject接口,以上面的MyJob类为例,我们通过调用HostingEnvironment.RegisterObject方法在ASP.NET中注册它

通过调用HostingEnvironment.UnregisterObject方法释放服务

当Appdomain要被回收的时候,会调用已注册对象IRegisteredObject中的Stop方法。

 	//
    // 摘要:
    //     Requests a registered object to unregister.
    //
    // 参数:
    //   immediate:
    //     true to indicate the registered object should unregister from the hosting environment
    //     before returning; otherwise, false.
    void Stop(bool immediate);

在第一次调用stop方法时,参数为false,执行完毕后,如果没有调用HostingEnvironment.UnregisterObject函数,隔30秒stop方法会再次被调用,参数为true,如果仍然没有调用HostingEnvironment.UnregisterObject函数,该服务就会被移除

不过我们使用的过程中并不会考虑第二次的调用,因为在第一次stop函数被调用的时候我们就会lock住正在执行的任务,并且一直到任务执行完成再释放lock,最后调用HostingEnvironment.UnregisterObject保证任务正常退出

对于这个流程上面的Myjob就是FluentScheduler提供的一个示例

IIS预加载

应用程序池回收之后,如果没有人访问网站,w3wp是不会启动的,那也就代表着我们的定时任务就不会启动了,所以我们需要在程序池被回收之后模拟访问一下该网站,我们可以通过写一个定时的程序每隔一秒钟访问一遍该网站来解决这个问题,但是为了解决这个问题多写一个程序并没有必要,因为微软已经提供了一个网站预加载的功能,每当应用程序池被回收,系统就会启动一个进程模拟访问一遍网站。这个功能似乎是iis7之后就有了,我下面演示的iis10的界面,其他版本的界面可能会稍微有所不同

1.修改应用程序池启动模式

2.开启对应网站预加载

3.增加配置编辑器,编写默认预加载的请求页面

至此,我们的服务就可以正常的运行啦

标签:asp,IIS,lock,HostingEnvironment,任务,调用,定时,FluentScheduler
From: https://www.cnblogs.com/Alex80/p/18012775

相关文章

  • 【译】发布 .NET Aspire 预览版 2(二)
    原文|DamianEdwards翻译|郑子铭组件更新组件包现在有单独的图标大多数Aspire组件的NuGet包现在都具有代表性图标,以便在NuGet包管理器对话框中更轻松地识别它们,并给体验带来一些视觉差异:MySqlConnector的组件和托管支持感谢社区成员BradleyGrainger(流行的MyS......
  • 【译】发布 .NET Aspire 预览版 2(一)
    原文|DamianEdwards翻译|郑子铭自上个月宣布并推出.NETAspire以来,我们收到的反馈非常惊人!通过问题和拉取请求对回购协议的参与一直激励着团队。我们正在深入了解开发人员在分布式云应用程序开发中如何使用(以及希望使用).NETAspire或其他组件。社区已经做出了一些很棒的......
  • Asp-Net-Core学习笔记:4.Blazor-Server入门
    本来今天开始是有其他的安排了,也没办法抽出那么多时间来学NetCore,不过我想做事情有始有终吧,除了gRPC还没跑起来之外,Blazor这部分也了解了一点,官网地址:https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor目前来说还不是很完善,真正的离线单页应用还处于预览版阶段。Blazo......
  • Asp-Net-Core学习笔记:5.构建和部署
    从上次开始学习Asp.NetCore以来,一直都是玩一玩,还没有什么机会用来实战,最近单位有个新的小项目,于是我用Asp.NetCore来尝尝新,结果也是非常OK,熟悉之后开发效率感觉和Django基本没差。那么进入正题,本文简单说说Asp.NetCore应用的构建和部署。构建构建是使用build命令,不过一般我......
  • Asp-Net-Core学习笔记:WebApi开发实践
    前言用AspNetCore做Api开发也有一段时间了,正好年底在做总结,做一个WebApi开发实践笔记。暂时想到的一些技术关键词,同时也作为本文的大纲,现在对这套技术体系的了解还不够深入,以后会持续更新这个Api开发实践~身份认证:JwtBearer分页:X.PagedList缓存ResponseCacheRedis:St......
  • Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室
    SignalR牛刀小试在MVP杨老师的博客里看到这么个东西,我还以为是NetCore3才推出的新玩意,原来是已经有很多年的历史了,那看来还是比较成熟的一个技术了。简介SignalR是一个.NETCore/.NETFramework的开源实时框架,SignalR的可使用WebSocket,ServerSentEvents和LongPolling......
  • Asp-Net-Core学习笔记:部署,早知道,还是docker,以及一点碎碎念
    前言AspNetCore技术栈在我们团队里的使用也有一段时间了,之前的部署方式一直是本地编译之后上传可执行文件到服务器,使用supervisor来管理进程这种很原始的方式。参考之前的文章:对于小项目来说尚可,够用,但是存在几个问题:每次更新花费的时间太长了,无论是Framework-Dependent还是S......
  • Asp .Net Core 系列:Asp .Net Core 集成 Panda.DynamicWebApi
    目录简介Asp.NetCore集成Panda.DynamicWebApi配置原理什么是POCOController?POCO控制器原理ControllerFeatureProvider实现自定义判断规则IApplicationModelConventionPanda.DynamicWebApi中的实现ConfigureApiExplorer()ConfigureSelector()ConfigureParameters()简介Panda......
  • IIS创建和管理虚拟网站
    实验介绍:本文会详细介绍创建虚拟站点的三种方法一:IP地址建立站点1.打开安装了IIS的windows,进入ip配置页面。添加几个ip,我这里添加的是192.168.1.209,192.168.1.210,192.168.1.2112.打开IIS管理页面,展开树形菜单,右键网站,点击添加网站3.在网站名称中输入你想设置的名称,物理......
  • DataSpell 2023:专注于数据,加速您的数据科学之旅 mac/win版
    JetBrainsDataSpell2023是一款专为数据科学家和数据分析师设计的集成开发环境(IDE)。这款IDE提供了强大的数据分析和可视化工具,旨在帮助用户更快速、更高效地进行数据科学工作。→→↓↓载DataSpell2023mac/win版 DataSpell2023在保持其一贯的数据处理、数据清洗、数据探......