<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Net5 版本以Core為底層非framework框架的windowservice 服務。
在VS裡叫WorkService 可以以CMD方式執行也可以以Windowservice方式執行,部署簡單。
Program.cs如下,是關鍵設定和啟動項
using Microsoft.Extensions.Hosting; using Quartz; using WorkerService.Common; using WorkerService.Job; namespace WorkerService { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).UseWindowsService() .ConfigureServices((hostContext, services) => { #region 原生work Service //自定義排程 //services.AddHostedService<Worker>(); #endregion #region quartz 原始版本 //這個版本 trigger job Schedule 是唯一關聯,不能一個組下多個任務 //services.AddQuartz(q => //{ // q.UseMicrosoftDependencyInjectionScopedJobFactory(); // // Create a "key" for the job // var jobKey = new JobKey("HelloTestJob"); // // Register the job with the DI container // q.AddJob<HelloTestJob>(opts => opts.WithIdentity(jobKey)); // // Create a trigger for the job // q.AddTrigger(opts => opts // .ForJob(jobKey) // link to the HelloWorldJob // .WithIdentity("HelloTestJob-trigger") // give the trigger a unique name // .WithCronSchedule("0/1 * * * * ?")); // run every 1 seconds //}); //services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true); #region quarzt 優化版本 // // Register the job, loading the schedule from configuration // q.AddJobAndTrigger<HelloTestJob>(hostContext.Configuration, "0/1 * * * * ?");//每秒執行一次 // q.AddJobAndTrigger<HelloTestJob2>(hostContext.Configuration, "0/1 * * * * ?"); #region 溫溼度 SF6 紅外圖片上傳 services.AddQuartz(q => { q.UseMicrosoftDependencyInjectionScopedJobFactory(); //每秒 0/1 * * * * ? 每小時 0 0 * * * ? // Register the job, loading the schedule from configuration q.AddJobAndTrigger<TemperatureJob>(hostContext.Configuration, "0 0 * * * ?"); q.AddJobAndTrigger<SF6Job>(hostContext.Configuration, "0 0 * * * ?"); q.AddJobAndTrigger<InfraredJob>(hostContext.Configuration, "0 0 * * * ?"); }); services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true); }); } }
原始的Host.CreateDefaultBuilder(args) 需要增加 .UseWindowsService() 支援 對windowservice
quarzt 在 NET5的nuget 中叫Quartz.Extensions.Hosting
services.AddHostedService<Worker>(); 是原始的windows定時任務版本
程式碼如下, 在await Task.Delay(1000, stoppingToken); 設定定時啟動的毫秒數就可以了
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.IO; using System.Threading; using System.Threading.Tasks; namespace WorkerService.Job.Test { public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger) { _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); FileStream stream = new FileStream(@"d:aa.txt", FileMode.Create);//fileMode指定是讀取還是寫入 StreamWriter writer = new StreamWriter(stream); writer.WriteLine("123456"+ DateTimeOffset.Now);//寫入一行,寫完後會自動換行 writer.Write("abc");//寫完後不會換行 writer.WriteLine("ABC"); writer.Close();//釋放記憶體 stream.Close();//釋放記憶體 await Task.Delay(1000, stoppingToken); } } } }
quartz 原始版本(program.cs程式碼截圖)
在目前這個quartz 3.3.3 版本中好像不能一個Key 下多個Job整合作業。所以每個job需要一個一個註冊。推薦使用優化版本
quarzt 優化版本(program.cs程式碼截圖)
對原始版本進行了封裝。在每一次呼叫的時候會註冊新的唯一範例。
以下是幫助類
using Microsoft.Extensions.Configuration; using Quartz; using System; namespace WorkerService.Common { public static class ServiceCollectionQuartzConfiguratorExtensions { public static void AddJobAndTrigger<T>( this IServiceCollectionQuartzConfigurator quartz, IConfiguration config, string cronSchedule) where T : IJob { // Use the name of the IJob as the appsettings.json key string jobName = typeof(T).Name; // Try and load the schedule from configuration var configKey = $"Quartz:{jobName}"; //var cronSchedule = config[configKey]; // Some minor validation if (string.IsNullOrEmpty(cronSchedule)) { throw new Exception($"No Quartz.NET Cron schedule found for job in configuration at {configKey}"); } // register the job as before var jobKey = new JobKey(jobName); quartz.AddJob<T>(opts => opts.WithIdentity(jobKey)); quartz.AddTrigger(opts => opts .ForJob(jobKey) .WithIdentity(jobName + "-trigger") .WithCronSchedule(cronSchedule)); // use the schedule from configuration } } }
以下是Job
using Microsoft.Extensions.Logging; using Quartz; using System; using System.IO; using System.Threading.Tasks; namespace WorkerService.Job.Test { [DisallowConcurrentExecution] public class HelloTestJob2 : IJob { private readonly ILogger<HelloTestJob2> _logger; public HelloTestJob2(ILogger<HelloTestJob2> logger) { _logger = logger; } public Task Execute(IJobExecutionContext context) { FileStream stream = new FileStream(@"d:aa1.txt", FileMode.Create);//fileMode指定是讀取還是寫入 StreamWriter writer = new StreamWriter(stream); writer.WriteLine("123456aaa" + DateTimeOffset.Now);//寫入一行,寫完後會自動換行 writer.Write("abc");//寫完後不會換行 writer.WriteLine("ABC"); writer.Close();//釋放記憶體 stream.Close();//釋放記憶體 return Task.CompletedTask; } } }
程式會根據Corn 設定的執行時間定期在Task Execute(IJobExecutionContext context)方法內執行
然後就是蠻搞笑的,大夥都不用Net5 嗎。寫服務上傳檔案。遇到問題搜尋NET5處理檔案上傳問題,居然都是空白的。 那我就只好自己寫解決方案了。
使用者端圖片上傳的HTTPHelper.cs部分程式碼如下
/// <summary> /// 上傳檔案 /// </summary> /// <param name="url">請求地址</param> /// <param name="path">檔案路徑(帶檔名)</param> /// <returns></returns> public static string HttpPostFile(string url, string path) { // 設定引數 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = "POST";string boundary = DateTime.Now.Ticks.ToString("X"); // 隨機分隔線 request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary; byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("rn--" + boundary + "rn"); byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("rn--" + boundary + "--rn"); int pos = path.LastIndexOf("\"); string fileName = path.Substring(pos + 1); //請求頭部資訊 StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name="file";filename="{0}"rnContent-Type:application/octet-streamrnrn", fileName)); byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString()); StringBuilder builder = new StringBuilder($"Content-Disposition:form-data;name="subPath"rnrntmswechat"); byte[] postHeaderBytestwo = Encoding.UTF8.GetBytes(builder.ToString()); FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); byte[] bArr = new byte[fs.Length]; fs.Read(bArr, 0, bArr.Length); fs.Close(); Stream postStream = request.GetRequestStream(); postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length); postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length); postStream.Write(bArr, 0, bArr.Length); postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length); postStream.Write(postHeaderBytestwo, 0, postHeaderBytestwo.Length); postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); postStream.Close(); //傳送請求並獲取相應迴應資料 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程式才開始向目標網頁傳送Post請求 Stream instream = response.GetResponseStream(); StreamReader sr = new StreamReader(instream, Encoding.UTF8); //返回結果網頁(html)程式碼 string content = sr.ReadToEnd(); return content; }
重點是伺服器端的接收,部分程式碼如下
try { var files = Request.Form.Files; if (files != null) { var file = files[0]; var location = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + $"Image\" + file.FileName; if (!Directory.Exists(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + $"Image\")) //判斷上傳資料夾是否存在,若不存在,則建立 { Directory.CreateDirectory(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + $"Image\"); //建立資料夾 } using (var stream = new FileStream(location, FileMode.Create)) { await file.CopyToAsync(stream); result = 1; } } //using (var reader = new StreamReader(Request.Body))//從身體裡讀取 //{ // var body = await reader.ReadToEndAsync(); //} } catch (Exception e ) { throw; }
哪怕你用的是檔案流上傳,不是表單提交。但是你的檔案依舊在Request.Form.Files 裡!!!!
但你也可以通過Request.body 讀到流
//using (var reader = new StreamReader(Request.Body))//從身體裡讀取 //{ // var body = await reader.ReadToEndAsync(); //}
到此這篇關於Net5 WorkService 繼承 Quarzt 以及 Net5處理檔案上傳的文章就介紹到這了,更多相關Net5 WorkService 繼承 Quarzt 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45