Net5 版本以Core为底层非framework框架的windowservice 服务。

在VS里叫WorkService 可以以CMD方式运行也可以以Windowservice方式运行,部署简单。

Program.cs如下,是关键配置和启动项

  1. using Microsoft.Extensions.Hosting;
  2. using Quartz;
  3. using WorkerService.Common;
  4. using WorkerService.Job;
  5.  
  6. namespace WorkerService
  7. {
  8. public class Program
  9. {
  10. public static void Main(string[] args)
  11. {
  12.  
  13. CreateHostBuilder(args).Build().Run();
  14. }
  15.  
  16. public static IHostBuilder CreateHostBuilder(string[] args) =>
  17. Host.CreateDefaultBuilder(args).UseWindowsService()
  18. .ConfigureServices((hostContext, services) =>
  19. {
  20.  
  21. #region 原生work Service
  22.  
  23. //自定义调度
  24.  
  25. //services.AddHostedService<Worker>();
  26.  
  27. #endregion
  28.  
  29. #region quartz 原始版本
  30.  
  31. //这个版本 trigger job Schedule 是唯一关联,不能一个组下多个任务
  32.  
  33. //services.AddQuartz(q =>
  34. //{
  35. // q.UseMicrosoftDependencyInjectionScopedJobFactory();
  36.  
  37. // // Create a "key" for the job
  38. // var jobKey = new JobKey("HelloTestJob");
  39.  
  40. // // Register the job with the DI container
  41. // q.AddJob<HelloTestJob>(opts => opts.WithIdentity(jobKey));
  42.  
  43. // // Create a trigger for the job
  44. // q.AddTrigger(opts => opts
  45. // .ForJob(jobKey) // link to the HelloWorldJob
  46. // .WithIdentity("HelloTestJob-trigger") // give the trigger a unique name
  47. // .WithCronSchedule("0/1 * * * * ?")); // run every 1 seconds
  48.  
  49. //});
  50.  
  51. //services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
  52.  
  53. #endregion
  54.  
  55. #region quarzt 优化版本
  56.  
  57. //services.AddQuartz(q =>
  58. //{
  59. // q.UseMicrosoftDependencyInjectionScopedJobFactory();
  60.  
  61. // // Register the job, loading the schedule from configuration
  62. // q.AddJobAndTrigger<HelloTestJob>(hostContext.Configuration, "0/1 * * * * ?");//每秒运行一次
  63.  
  64. // q.AddJobAndTrigger<HelloTestJob2>(hostContext.Configuration, "0/1 * * * * ?");
  65. //});
  66.  
  67. //services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
  68.  
  69. #endregion
  70.  
  71. #region 温湿度 SF6 红外图片上传
  72.  
  73. services.AddQuartz(q =>
  74. {
  75. q.UseMicrosoftDependencyInjectionScopedJobFactory();
  76.  
  77. //每秒 0/1 * * * * ? 每小时 0 0 * * * ?
  78. // Register the job, loading the schedule from configuration
  79. q.AddJobAndTrigger<TemperatureJob>(hostContext.Configuration, "0 0 * * * ?");
  80.  
  81. q.AddJobAndTrigger<SF6Job>(hostContext.Configuration, "0 0 * * * ?");
  82.  
  83. q.AddJobAndTrigger<InfraredJob>(hostContext.Configuration, "0 0 * * * ?");
  84. });
  85.  
  86. services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
  87.  
  88. #endregion
  89.  
  90. });
  91. }
  92.  
  93. }

原始的 Host.CreateDefaultBuilder(args) 需要增加  .UseWindowsService()  支持 对windowservice

quarzt 在 NET5的nuget 中叫 Quartz.Extensions.Hosting

services.AddHostedService<Worker>();   是原始的windows定时任务版本

代码如下, 在 await Task.Delay(1000, stoppingToken);  设定定时启动的毫秒数就可以了

  1. using Microsoft.Extensions.Hosting;
  2. using Microsoft.Extensions.Logging;
  3. using System;
  4. using System.IO;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7.  
  8. namespace WorkerService.Job.Test
  9. {
  10. public class Worker : BackgroundService
  11. {
  12. private readonly ILogger<Worker> _logger;
  13.  
  14. public Worker(ILogger<Worker> logger)
  15. {
  16. _logger = logger;
  17. }
  18.  
  19. protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  20. {
  21. while (!stoppingToken.IsCancellationRequested)
  22. {
  23. _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
  24.  
  25. FileStream stream = new FileStream(@"d:\aa.txt", FileMode.Create);//fileMode指定是读取还是写入
  26. StreamWriter writer = new StreamWriter(stream);
  27. writer.WriteLine("123456"+ DateTimeOffset.Now);//写入一行,写完后会自动换行
  28. writer.Write("abc");//写完后不会换行
  29. writer.WriteLine("ABC");
  30. writer.Close();//释放内存
  31. stream.Close();//释放内存
  32.  
  33. await Task.Delay(1000, stoppingToken);
  34. }
  35. }
  36. }
  37. }

quartz 原始版本(program.cs代码截图)

在目前这个quartz 3.3.3 版本中好像不能一个Key 下多个Job集成作业。所以每个job需要一个一个注册。推荐使用优化版本

quarzt 优化版本(program.cs代码截图)

对原始版本进行了封装。在每一次调用的时候会注册新的唯一实例。

以下是帮助类

  1. using Microsoft.Extensions.Configuration;
  2. using Quartz;
  3. using System;
  4.  
  5. namespace WorkerService.Common
  6. {
  7. public static class ServiceCollectionQuartzConfiguratorExtensions
  8. {
  9. public static void AddJobAndTrigger<T>(
  10. this IServiceCollectionQuartzConfigurator quartz,
  11. IConfiguration config, string cronSchedule)
  12. where T : IJob
  13. {
  14. // Use the name of the IJob as the appsettings.json key
  15. string jobName = typeof(T).Name;
  16.  
  17. // Try and load the schedule from configuration
  18. var configKey = $"Quartz:{jobName}";
  19. //var cronSchedule = config[configKey];
  20.  
  21. // Some minor validation
  22. if (string.IsNullOrEmpty(cronSchedule))
  23. {
  24. throw new Exception($"No Quartz.NET Cron schedule found for job in configuration at {configKey}");
  25. }
  26.  
  27. // register the job as before
  28. var jobKey = new JobKey(jobName);
  29. quartz.AddJob<T>(opts => opts.WithIdentity(jobKey));
  30.  
  31. quartz.AddTrigger(opts => opts
  32. .ForJob(jobKey)
  33. .WithIdentity(jobName + "-trigger")
  34. .WithCronSchedule(cronSchedule)); // use the schedule from configuration
  35. }
  36. }
  37. }

以下是Job

  1. using Microsoft.Extensions.Logging;
  2. using Quartz;
  3. using System;
  4. using System.IO;
  5. using System.Threading.Tasks;
  6.  
  7. namespace WorkerService.Job.Test
  8. {
  9.  
  10. [DisallowConcurrentExecution]
  11. public class HelloTestJob2 : IJob
  12. {
  13. private readonly ILogger<HelloTestJob2> _logger;
  14.  
  15. public HelloTestJob2(ILogger<HelloTestJob2> logger)
  16. {
  17. _logger = logger;
  18.  
  19. }
  20.  
  21. public Task Execute(IJobExecutionContext context)
  22. {
  23. FileStream stream = new FileStream(@"d:\aa1.txt", FileMode.Create);//fileMode指定是读取还是写入
  24. StreamWriter writer = new StreamWriter(stream);
  25. writer.WriteLine("123456aaa" + DateTimeOffset.Now);//写入一行,写完后会自动换行
  26. writer.Write("abc");//写完后不会换行
  27. writer.WriteLine("ABC");
  28. writer.Close();//释放内存
  29. stream.Close();//释放内存
  30.  
  31. return Task.CompletedTask;
  32. }
  33. }
  34.  
  35. }

程序会根据Corn 设定的运行时间定期在 Task Execute(IJobExecutionContext context)方法内运行

然后就是蛮搞笑的,大伙都不用Net5 吗。写服务上传文件。遇到问题搜索NET5处理文件上传问题,居然都是空白的。 那我就只好自己写解决方案了。

客户端图片上传的HTTPHelper.cs部分代码如下

  1. /// <summary>
  2. /// 上传文件
  3. /// </summary>
  4. /// <param name="url">请求地址</param>
  5. /// <param name="path">文件路径(带文件名)</param>
  6. /// <returns></returns>
  7. public static string HttpPostFile(string url, string path)
  8. {
  9. // 设置参数
  10. HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
  11. CookieContainer cookieContainer = new CookieContainer();
  12. request.CookieContainer = cookieContainer;
  13. request.AllowAutoRedirect = true;
  14. request.Method = "POST";string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
  15. request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
  16. byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
  17. byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
  18.  
  19. int pos = path.LastIndexOf("\\");
  20. string fileName = path.Substring(pos + 1);
  21.  
  22. //请求头部信息
  23. StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
  24. byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
  25.  
  26. StringBuilder builder = new StringBuilder($"Content-Disposition:form-data;name=\"subPath\"\r\n\r\ntmswechat");
  27. byte[] postHeaderBytestwo = Encoding.UTF8.GetBytes(builder.ToString());
  28.  
  29. FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
  30. byte[] bArr = new byte[fs.Length];
  31. fs.Read(bArr, 0, bArr.Length);
  32. fs.Close();
  33.  
  34. Stream postStream = request.GetRequestStream();
  35. postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
  36. postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
  37. postStream.Write(bArr, 0, bArr.Length);
  38. postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
  39. postStream.Write(postHeaderBytestwo, 0, postHeaderBytestwo.Length);
  40. postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
  41. postStream.Close();
  42.  
  43. //发送请求并获取相应回应数据
  44. HttpWebResponse response = request.GetResponse() as HttpWebResponse;
  45. //直到request.GetResponse()程序才开始向目标网页发送Post请求
  46. Stream instream = response.GetResponseStream();
  47. StreamReader sr = new StreamReader(instream, Encoding.UTF8);
  48. //返回结果网页(html)代码
  49. string content = sr.ReadToEnd();
  50. return content;
  51. }

重点是服务端的接收,部分代码如下

  1. try
  2. {
  3. var files = Request.Form.Files;
  4. if (files != null)
  5. {
  6. var file = files[0];
  7.  
  8. var location = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + $"Image\\" + file.FileName;
  9.  
  10. if (!Directory.Exists(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + $"Image\\")) //判断上传文件夹是否存在,若不存在,则创建
  11. {
  12. Directory.CreateDirectory(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + $"Image\\"); //创建文件夹
  13. }
  14.  
  15. using (var stream = new FileStream(location, FileMode.Create))
  16. {
  17. await file.CopyToAsync(stream);
  18. result = 1;
  19. }
  20. }
  21.  
  22. //using (var reader = new StreamReader(Request.Body))//从身体里读取
  23. //{
  24.  
  25. // var body = await reader.ReadToEndAsync();
  26.  
  27. //}
  28. }
  29. catch (Exception e )
  30. {
  31.  
  32. throw;
  33. }

哪怕你用的是文件流上传,不是表单提交。但是你的文件依旧在Request.Form.Files 里!!!!

但你也可以通过Request.body 读到流

  1. //using (var reader = new StreamReader(Request.Body))//从身体里读取
  2. //{
  3.  
  4. // var body = await reader.ReadToEndAsync();
  5.  
  6. //}

Net5 WorkService 继承 Quarzt 以及 Net5处理文件上传的更多相关文章

  1. Spring Mvc 笔记二之异常和文件上传

    spring mvc的异常与文件上传 1.异常: spring注解版的异常有局部异常和全局异常                1.局部异常对单个controller有效;(在controller类写一 ...

  2. Blazor组件自做九: 用20行代码实现文件上传,浏览目录功能 (3)

    接上篇 Blazor组件自做九: 用20行代码实现文件上传,浏览目录功能 (2) 7. 使用配置文件指定监听地址 打开 appsettings.json 文件,加入一行 "UseUrls&q ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(32)-swfupload多文件上传[附源码]

    系列目录 文件上传这东西说到底有时候很痛,原来的asp.net服务器控件提供了很简单的上传,但是有回传,还没有进度条提示.这次我们演示利用swfupload多文件上传,项目上文件上传是比不可少的,大家 ...

  4. Struts2入门(七)——Struts2的文件上传和下载

    一.前言 在之前的随笔之中,我们已经了解Java通过上传组件来实现上传和下载,这次我们来了解Struts2的上传和下载. 注意:文件上传时,我们需要将表单提交方式设置为"POST" ...

  5. THINKPHP源码学习--------文件上传类

    TP图片上传类的理解 在做自己项目上传图片的时候一直都有用到TP的上传图片类,所以要进入源码探索一下. 文件目录:./THinkPHP/Library/Think/Upload.class.php n ...

  6. 【原创】JEECMS v6~v7任意文件上传漏洞(2)

    文章作者:rebeyond 受影响版本:v6~v7 漏洞说明: JEECMS是国内Java版开源网站内容管理系统(java cms.jsp cms)的简称.该系统基于java技术开发,继承其强大.稳定 ...

  7. 【原创】JEECMS v6~v7任意文件上传漏洞(1)

    文章作者:rebeyond 受影响版本:v6~v7 漏洞说明: JEECMS是国内Java版开源网站内容管理系统(java cms.jsp cms)的简称.该系统基于java技术开发,继承其强大.稳定 ...

  8. 【C#公共帮助类】FTPClientHelper帮助类,实现文件上传,目录操作,下载等动作

    关于本文档的说明 本文档使用Socket通信方式来实现ftp文件的上传下载等命令的执行 欢迎传播分享,必须保持原作者的信息,但禁止将该文档直接用于商业盈利. 本人自从几年前走上编程之路,一直致力于收集 ...

  9. 【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】

    一.struts2文件上传 1.上传文件的时候要求必须使得表单的enctype属性设置为multipart/form-data,把它的method属性设置为post 2.上传单个文件的时候需要在Act ...

  10. 几款极好的 JavaScript 文件上传插件

    文件上传功能作为网页重要的组成部分,几乎无处不在,从简单的单个文件上传到复杂的批量上传.拖放上传,需要开发者花费大量的时间和精力去处理,以期实现好用的上传功能.这篇文章向大家推荐几款很棒的 JavaS ...

随机推荐

  1. java基础-java面向对象01-day08

    1. 一个简单的类 认识类 成员变量 类方法 public class Person { //类的成员变量 int age; String name; double height; double we ...

  2. docker 原理之 user namespace(下)

    1. user namespace user namespace 主要隔离了安全相关的标识符和属性,包括用户 ID,用户组 ID,key 和 capabilities 等.同样一个用户 id 在不同 ...

  3. 帮助编写异步代码的ESLint规则

    调试 JavaScript 中的异步代码有时就像在雷区中穿梭.你不知道 console.log 会在何时何地打印出来,也不知道代码是如何执行的. 你很难正确构造异步代码,使其按照你的意图以正确的顺序执 ...

  4. 如果诸葛亮会编程,用Java写出师表...

    继上一篇 "如果诸葛亮用C#写出师表..."后,站长想自己的第一语言是Java,虽然平时工作上用的不多,也用Java实现一遍吧,改改就是了,无非就是: C#的Console.Wri ...

  5. SpringMVC05——SSM整合

    整合SSM 需求:熟练掌握MySQL数据库,Spring,JavaWeb及MyBatis知识,简单的前端知识 CREATE DATABASE `ssmbuild`; USE `ssmbuild`; D ...

  6. Jmeter学习之五_跟踪被测试服务器的performance

    Jmeter学习之五_跟踪被测试服务器的performance 背景 这几天简单学习了一些基本的测试过程. 可以实现一些简单基本的功能了. 今天晚上继续进行了jmeter的一些学习. 想着可以在测试人 ...

  7. [转帖]Linux—vi/vim全局替换

    https://www.jianshu.com/p/4daa5dbc7dd5 vim全局替换   在linux系统中编辑文件或者配置时,常常会用到全局替换功能. 语法格式 :%s/oldWords/n ...

  8. stress-NG 磁盘测试结果-全国产信创部分验证

    stress-NG 磁盘测试结果 摘要 前几天分别还是用了redis-benchmark还有specjvm2008进行了多种系统的压测 得出了信创CPU的一些简单结论 但是一直还没有压测磁盘, 今天想 ...

  9. 【转帖】TCP内核参数

    https://www.cnblogs.com/chia/p/7799231.html tcp_syn_retries :INTEGER默认值是5对于一个新建连接,内核要发送多少个 SYN 连接请求才 ...

  10. [转帖][问题已处理]-kubernetes中2次不同的oom处理

    https://dandelioncloud.cn/article/details/1598699030236577793 起因: 同事反馈 服务挂了,kuboard上查看是服务挂掉了,livenes ...