Aspnet Zero中使用Windows service (Topshelf)来承载Quartz.net任务
Aspnet Zero使用Windows service (Topshelf)来承载Quartz.net任务
网上有很多关于如何使用Topshelf创建ABP的Quartz windows服务,但很少(没有)有介绍如何配合Aspnet Zero使用的文章,本文记录集成过程,以供参考。
在官方Aspnet Zero模板解决方案中建立Console类型的项目,并安装以下buget package:
TopshelfAbp.QuartzAbp.Castle.Log4NetAbp.AspnetCore(后面有用到)添加引用
MyCompanyName.AbpZeroTemplate.Core和MyCompanyName.AbpZeroTemplate.Core项目最终引用如图:

创建Module文件,
- 添加相关DependsOn属性;
abpZeroTemplateEntityFrameworkCoreModule.SkipDbSeed = true;这里我们需要禁用数据库初始化动作,因为所有的初始化动作都在Host端完成;- 设置数据库连接字符串
Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString( AbpZeroTemplateConsts.ConnectionStringName );
最终文件如下:
namespace MyCompanyName.AbpZeroTemplate.WinService
{
[DependsOn(typeof(AbpZeroTemplateCoreModule),
typeof(AbpZeroTemplateEntityFrameworkCoreModule),
typeof(AbpQuartzModule)
)]
public class AbpZeroWinServiceModule : AbpModule
{
private readonly IConfigurationRoot _appConfiguration; public AbpZeroWinServiceModule(AbpZeroTemplateEntityFrameworkCoreModule abpZeroTemplateEntityFrameworkCoreModule)
{
abpZeroTemplateEntityFrameworkCoreModule.SkipDbSeed = true; _appConfiguration = AppConfigurations.Get(
typeof(AbpZeroWinServiceModule).GetAssembly().GetDirectoryPathOrNull(),
addUserSecrets: true
);
} public override void PreInitialize()
{
//Set default connection string
Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString(
AbpZeroTemplateConsts.ConnectionStringName
);
} public override void Initialize()
{
this.IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); }
}
}
修改Program.cs文件
- 设置工作目录
Directory.SetCurrentDirectory(currentDirectory);, 目的是为了保证工作在windows service时log文件存放目录正确,如果不设置, 工作在windows service时log文件将会存放在system32目录中 - 注册IdentityRegistrar以及添加abp依赖,这一步是必须的,否则会出现依赖错误:
Castle.MicroKernel.Handlers.HandlerException: 'Can't create component 'Portal.Authorization.Users.UserManager' as it has dependencies to be satisfied.
添加abp依赖的同时我们同时添加log4net和插件支持.(注意路径)var services = new ServiceCollection();
IdentityRegistrar.Register(services); services.AddAbp<AbpZeroWinServiceModule>(options =>
{
//Configure Log4Net logging
options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseAbpLog4Net().WithConfig(Path.Combine(currentDirectory, $"log4net.config"))
); options.PlugInSources.AddFolder(Path.Combine(currentDirectory, "Plugins"), SearchOption.AllDirectories);
});
完整Program.cs代码如下:
class Program
{
static void Main(string[] args)
{
var currentDirectory = typeof(Program).GetAssembly().GetDirectoryPathOrNull();
// 设置工作目录. 保证工作在windows service时log文件存放目录正确
// 如果不设置, 工作在windows service时log文件将会存放在system32目录中
Directory.SetCurrentDirectory(currentDirectory); var services = new ServiceCollection();
IdentityRegistrar.Register(services); services.AddAbp<AbpZeroWinServiceModule>(options =>
{
//Configure Log4Net logging
options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseAbpLog4Net().WithConfig(Path.Combine(currentDirectory, $"log4net.config"))
); options.PlugInSources.AddFolder(Path.Combine(currentDirectory, "Plugins"), SearchOption.AllDirectories);
}); HostFactory.Run(x =>
{
x.Service<AbpZeroWinService>(s =>
{
s.ConstructUsing(name => new AbpZeroWinService());
s.WhenStarted((tc, hostControl) => tc.Start(hostControl));
s.WhenStopped((tc, hostControl) => tc.Stop(hostControl));
}); x.RunAsLocalSystem();
x.StartAutomatically(); x.SetDescription("ABP服务测试");
x.SetDisplayName("ABPTestService");
x.SetServiceName("ABPTestService");
});
}
}
- 设置工作目录
启动ABP. Windows service启动时会调用
s.ConstructUsing(name => new AbpZeroWinService());, 因此我们在AbpZeroWinService中启动ABP.- 创建
AbpZeroWinService类继承自ServiceControl, 在Start中初始化AbpBootstrapper, 同时在停止Stop中销毁AbpBootstrapper. 代码如下:
public class AbpZeroWinService : ServiceControl
{
private AbpBootstrapper _bootstrapper;
public bool Start(HostControl hostControl)
{
_bootstrapper = IocManager.Instance.Resolve<AbpBootstrapper>();
_bootstrapper.Initialize();
return true;
} public bool Stop(HostControl hostControl)
{
_bootstrapper.Dispose();
return true;
}
}
- 创建
quartz.net的配置
quartz.config中必须使用AdoJobStore类型,并且使用和Host一样的Quartz数据库连接,这样才能实现在host上添加任务,最终由windows service来执行任务。
(请在HostModule的PreInitialize方法中禁用Job执行Configuration.BackgroundJobs.IsJobExecutionEnabled = false;)运行前确保Quartz.net数据库已建立,如何建立请参考Quartz.net官方文档
以上如有错误的地方请大家指正! 如果更好的实现方式,也请分享一下。
最后给出WindowService项目的源码,Aspnet Zero的项目自行解决。
source code
Aspnet Zero中使用Windows service (Topshelf)来承载Quartz.net任务的更多相关文章
- Win7中不能调试windows service
多年前玩过一次windows service,觉得挺简单的. 这次工作要维护产品中的windows service,发现不是那么简单,vs附加调试器的窗体中无法找到windows service进程. ...
- WCF Windows Service Using TopShelf and ServiceModelEx z
http://lourenco.co.za/blog/2013/08/wcf-windows-service-using-topshelf-and-servicemodelex/ There are ...
- 创建需要计时器的windows service
1.在VS中建立windows service后,应该添加一个安装程序. 2.在默认的Service1.cs设计界面右键,添加安装程序,生成ProjectInstaller.包含两个类serviceP ...
- C# 通过 Quartz .NET 实现Timer Job并将其注册成为Windows Service
之前的一篇文章讲述了如何通过 Quartz .NET 实现 Timer Job (http://www.cnblogs.com/mingmingruyuedlut/p/8037263.html) 在此 ...
- .NET 6学习笔记(2)——通过Worker Service创建Windows Service
通过Visual Studio中的Windows Service模板,我么可以创建.NET Framework版本的Windows Service,网络上对此已有详细且丰富的各路教程.但在我们升级到. ...
- 如何托管ASP.NET Core应用到Windows Service中
(此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:正在构思一个中间件的设计,考虑是否既可以使用最新的技术,也可以兼顾传统的部署模式.所以有 ...
- .NET开发Windows Service程序 - Topshelf
在实际项目开发过程中,会经常写一些类似定时检查,应用监控的应用.这类应用在windows平台通常都会写成window service程序. 在百度上搜索一下'c#开发windows service', ...
- quartz.net结合Topshelf实现windows service服务托管的作业调度框架
topshelf可以很简单方便的实现windows service服务,详见我的一篇博客的介绍 http://www.cnblogs.com/xiaopotian/articles/5428361.h ...
- ASP.NET Core应用到Windows Service中
托管到Windows Service中 众所周知,ASP.NET Core采用了和传统ASP.NET不同的托管和HTTP处理方式,即把服务器和托管环境完全解耦. ASP.NET Core内置了两个HT ...
随机推荐
- Python Ethical Hacking - VULNERABILITY SCANNER(8)
Implementing Code To Discover XSS in Parameters 1. Watch the URL of the XSS reflected page carefully ...
- 集训作业 洛谷P3913 车的攻击
这个题一开始被我想复杂了,但总体差不多. 脑子清醒后我直接看他占领了几条长,几条宽,比如一个长3宽3的地图. 被占领了一条宽,就可以看成一个长3宽2的地图.这个长3宽2的地图就是出去可以被攻击的点剩下 ...
- Arctic Code Vault Contributor 上榜了 go-admin v1.1 beta 版本发布
Arctic Code Vault Contributor 上榜了,内心比较喜悦,谢谢开源社区的支持,也谢谢广大 coder 的支持: go-admin 是一个基于 Gin + Vue + Eleme ...
- MySQL数据库---记录相关操作
序 表中记录的相关操作一共四种:插入,更新,删除.查询.其中使用最多,也是最难的就是查询. 记录的插入 1. 插入完整数据(顺序插入) 语法一: INSERT INTO 表名(字段1,字段2,字段3… ...
- CentOS 7配置网卡信息,并设置yum为阿里云的镜像源
一.问题场景 使用virtualbox创建的centos 7版本的linux虚拟机,使用ping mirrors.aliyun.com有返回,但是wget -O /etc/yum.repos.d/ep ...
- 时间复杂度为O(nlogn)的排序算法
时间复杂度为O(nlogn)的排序算法(归并排序.快速排序),比时间复杂度O(n²)的排序算法更适合大规模数据排序. 归并排序 归并排序的核心思想 采用"分治思想",将要排序的数组 ...
- 一个有趣的问题, 你知道SqlDataAdapter中的Fill是怎么实现的吗
一:背景 1. 讲故事 最近因为各方面原因换了一份工作,去了一家主营物联柜的公司,有意思的是物联柜上的终端是用 wpf 写的,代码也算是年久失修,感觉技术债还是蛮重的,前几天在调试一个bug的时候,看 ...
- 一文说通C#中的异步编程
天天写,不一定就明白. 又及,前两天看了一个关于同步方法中调用异步方法的文章,里面有些概念不太正确,所以整理了这个文章. 一.同步和异步. 先说同步. 同步概念大家都很熟悉.在异步概念出来之前,我 ...
- React Native 报错 Error: spawn EACCES 权限
权限不足,运行命令修改权限 chmod android/gradlew
- 【NeurlPS2019】Positional Normalization 位置归一化
作者提出,当前的BatchNorm, GroupNorm, InstanceNorm在空间层面归一化信息,同时丢弃了统计值.作者认为这些统计信息中包含重要的信息,如果有效利用,可以提高GAN和分类网络 ...