.Net 5 通用主机实战

前言

最近公司有个定时发邮件的需求,就是另一个产品会生成很多邮件,但由于这个产品太过老了,而且开发商并不是我方,这些邮件无法发送给相关收邮件的人,于是就想通过.Net Core里的通用主机(官方叫:辅助角色服务应用程序),做成一个Window服务,实现这一功能。

环境

运行环境:.Net 5
开发环境:VS2019 16.8.2

安装

在创建页面找到Worker Service模板
在这里插入图片描述
初始化完:

public class Program
    {
        public static void Main(string[] args)
        {
            var host=CreateHostBuilder(args).Build();
            host.Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    
                    services.AddHostedService<Worker>();
                });
    }

从代码中发现特别熟悉,跟Asp.Net Core Web几乎一模一样,只不过没有监听http请求,而是通过依赖注入的方式注入了一个继承BackgroundService的类
在这里插入图片描述
相当于这里继承BackgroundService就实现了一个能长时间运行的主机服务,那就很简单了,只需要把发送邮件的放在ExecuteAsync,需求是有三个mysql数据库,每隔5分钟去查一次,如果有邮件,则发送给相关方,我这里用的是Dapper+mysql,所以通过依赖注入实现了Dapper的创建。

public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly DapperClient _qid1;
        private readonly DapperClient _qid2;
        private readonly DapperClient _qid3;
        public Worker(ILogger<Worker> logger,IDapperFactory dapperFactory)
        {
            _logger = logger;
            this._qid1 = dapperFactory.CreateClient("qid1");
            this._qid2 = dapperFactory.CreateClient("qid2");
            this._qid3 = dapperFactory.CreateClient("qid3");
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            try
            {
                _logger.LogInformation($"Send Email Service running at: {DateTimeOffset.Now}");
                Task t1= SendEmailTask(_qid1, stoppingToken);
                Task t2= SendEmailTask(_qid2, stoppingToken);
                Task t3 = SendEmailTask(_qid3, stoppingToken);

                await Task.WhenAll(t1, t2,t3);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message);
            }
        }

        protected async Task SendEmailTask(DapperClient dapper,CancellationToken stoppingToken)
        {
            await Task.Run(async () =>
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    EmailHandler handler = new EmailHandler(dapper);
                    await handler.SearchEmailServer();
                    await Task.Delay(new TimeSpan(0, 0, 5, 0));
                }
            },stoppingToken);
        }
    }
部署

正常情况下,在服务主机上打开.exe文件就能正常运行了,但考虑到别的同事可能会误关程序,于是需要把这个服务注册成一个系统的服务。
需要在CreateHostBuilder中加上 .UseWindowsService()

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    
                    services.AddHostedService<Worker>();
                })
                .UseWindowsService();

通过windows自带的sc.exe 工具(需要管理员权限),进入cmd命令行,
sc.exe create DemoWorker binpath= publish\xxxx.exe 创建服务
sc.exe start WorkerServicesName 启动服务
sc.exe stop WorkerServicesName 停止服务
sc.exe delete WorkerServicesName 删除服务

另外可以通过管理工具,进入服务,找到服务,设置为自动启动,这样就算服务器关机重启了,也能正常工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值