只有累積,沒有奇蹟

2023年10月10日 星期二

[NETCore] ASP.NET Core 3.0 Worker Service 搭配 Coravel 建立排程服務

前言
如果一直有在 follow 消息的朋友可以發現在 ASP.NET 3.0 有新增 Work Services 專案範本,可以透過幾個簡單的步驟使用 Workers with Windows Services 服務,詳細可以參考微軟官網對於 worker Service 的介紹文章 .NET Core Workers as Windows Services,在上一篇介紹了 ASP.NET Core 中的輕量級排程套件 Coravel,這一篇就來介紹整合 ASP.NET Core Worker Service 與 Coravel 的應用,當然如往常一樣若有問題或是錯誤的地方歡迎網路的高手大大給予指導或討論

建立 Worker Service 專案
在開始之前如果沒有下載 ASP.NET Core 3.0 的朋友,可以到 ASP.NET Core 3.0 下載其 SDK 與相關內容,下載完畢之後接著建立一個名為 WorkerServiceLab 的 ASP.NET Core Application 應用程式專案,在輸入完專案名稱之後在上方選擇 ASP.NET Core 3.0,並且在下方的專案範本選擇 Worker Service,

ASP.NET Core 3.0 的異動 - Program.cs
在開始之前我們先來開啟 program.cs 看一下 worker Service 範本內容
  1. namespace WorkServiceLab
  2. {
  3. public class Program
  4. {
  5. public static void Main(string[] args)
  6. {
  7. CreateHostBuilder(args).Build().Run();
  8. }
  9.  
  10. public static IHostBuilder CreateHostBuilder(string[] args) =>
  11. Host.CreateDefaultBuilder(args)
  12. .ConfigureServices((hostContext, services) =>
  13. {
  14. services.AddHostedService<Worker>();
  15. });
  16. }
  17. }
如果有在寫 ASP.NET Core 2.2 的朋友可以發現在 createHostBuilder 中 webHostBuilder 已經消失不見,範本中已經改為 HostBuilder,也就是說在 ASP.NET Core 3.0 將會由 Host 取代原來 webHost,這些更新在 pre早期 3.0 preview 2 中有提到未來會以 Generic Host 為主,IWebHostBuilder 並不會就此消失將會繼續保留,詳細細節可以參考 preview2 文章 : 傳送門
如果對於 Generic Host 有興趣,可以參考之前小弟撰寫的相關系列文章

  • ASP.NET Core 建立排程服務 - 使用 Generic Host 搭配 Quartz.Net - Hosted Builder
  • ASP.NET Core 建立排程服務 - 使用 Generic Host 搭配 Quartz.Net - Quartz.NET
  • ASP.NET Core 建立排程服務 - 使用 Generic Host 搭配 Quartz.Net - Windows Service

  • 使用 Coravel
    建立好 worker service 專案,也簡單介紹關於 program.cs 在 ASP.NET Core 3.0 的差異,這邊再繼續介紹 worker service 如何與 coravel 整合的步驟

    安裝 Coravel 套件
    在 ASP.NET Core 中的排程利器 - Coravel 有介紹過基本使用方式,可以透過 Nuget console 進行下載的動作,在 Nuget Package Console 輸入下列指令
    1. Install-Package Coravel -Version 3.0.0
    安裝完畢之後到專案檔底下確認是否有安裝成功
    1. <ItemGroup>
    2. <PackageReference Include="Coravel" Version="3.0.0" />
    3. </ItemGroup>

    新增 Job 類別
    建立 GetDatetimeJob  類別並實作 IInvocable,代碼如下
    1. using Coravel.Invocable;
    2.  
    3. namespace CoravelLab
    4. {
    5. public class GetDatetimePreFiveSecondJob : IInvocable
    6. {
    7. public Task Invoke()
    8. {
    9. Console.WriteLine($"Worker running at: {DateTime.Now}");
    10. return Task.CompletedTask;
    11. }
    12. }
    13. }

    CreateHostBuilder 加入 Job
    繼續回到 program.cs 要在 progmram.cs 加入註冊 Job 的動作,因此我們在 ConfigureServices 中透過 AddSchedule 與 AddTransient 來註冊配置要執行的 Job 排程類別
    1. public static IHostBuilder CreateHostBuilder(string[] args) =>
    2. Host.CreateDefaultBuilder(args)
    3. .ConfigureServices((hostContext, services) =>
    4. {
    5. services.AddScheduler();
    6. services.AddTransient<GetDatetimeJob>();
    7. });
    註冊完服務之後接著來設定 Job 執行的頻率,在 Coravel 排程執行時間是透過程式內設定,套件本身建提供多種方法讓開發者設定執行的時間,例如我希望排程要每秒執行一次可以透過 EverySecond() 設定,並且在 Main 加入執行頻率
    1. public static void Main(string[] args)
    2. {
    3. IHost host = CreateHostBuilder(args).Build();
    4. host.Services.UseScheduler(scheduler =>
    5. {
    6. scheduler.Schedule<GetDatetimeJob>()
    7. .EverySecond();
    8. });
    9. host.Run();
    10. }
    完成上述代碼修改與設定之後,執行專案可以看到輸出結果如下

    加入 Log 及錯誤處理
    在真實的世界中當然不可能像上面介紹那麼簡單,在實務上會在執行時加上 log 機制方便記錄 Job 執行的狀況,這樣可以在執行結果不如預期時或是異常訊息時得知更多的資訊,在 coravel 套件中也支援 log 與 error 處理,我們可以在代碼中加入  LogScheduledTaskProgress  紀錄執行的 log 以及  onError  錯誤處理 
    1. public static void Main(string[] args)
    2. {
    3. IHost host = CreateHostBuilder(args).Build();
    4. host.Services.UseScheduler(scheduler =>
    5. {
    6. scheduler.Schedule<GetDatetimeJob>()
    7. .EverySecond();
    8. })
    9. .LogScheduledTaskProgress(host.Services.GetService<ILogger<IScheduler>>())
    10. .OnError((exception) =>
    11. Console.WriteLine(exception.Message)); ;
    12.  
    13. host.Run();
    14. }
    這樣在執行過程中發生錯誤才會 catch 到相對應錯誤,如下所示

    Windows Service 
    完成上述建立排程服務的動作下一步就是幫排程 Application 找一個合適的家,在 Windows 中開發完 worker service App 之後可以選擇將應用程式註冊為服務使用,在 ASP.NET Core 2.2 中可能會使用 ServiceBaseLifeTime 在 Windows 服務的生命週期行為進行操作,在 ASP.NET Core 3.0 則可以透過 nuget 安裝  Microsoft.Extensions.Hosting.WindowsServices  來協助此需求
    安裝後就可以在 CreateHostBuilder 內使用 UseWindowsService 在啟動或是停止進行操作或是紀錄 log
    1. public static IHostBuilder CreateHostBuilder(string[] args) =>
    2. Host.CreateDefaultBuilder(args)
    3. .UseWindowsService()
    4. .ConfigureServices((hostContext, services) =>
    5. {
    6. services.AddScheduler();
    7. //services.AddTransient<GetDatetimeJob>();
    8. });
    9. }


    參考
    .NET Core Workers as Windows Services

    Related Posts:

    • [.NET] ASP.NET 特殊資料夾 [Special Folders] 在Visual Studio 2008 建立新的Web網站時,會同時新增一個特別的資料夾叫做「App_Data」,此資料夾是預留給資料庫使用,如Sql Server 2005 Express版,副檔名為「.mdf」的檔案。ASP.NET中有一些特殊的資料夾名稱,可以在專案點右鍵 > 加入 > 加入ASP.NET資料夾;將特殊資料夾加到專案中 ASP.NET Special Folders    … Read More
    • [.NET] ASP.NET Application 概述 ASP.NET 處理請求的兩個步驟 當用戶發送一個請求到IIS(這裡指IIS 5.0 & IIS 6.0),ASP.NET 處理請求的步驟有兩種 1. 建立一個可以處理用戶端傳來請求Request的環境(ASP.NET Environment),包括建立application object(應用程式)、Ruquest、Response、Context Object等物件來處理此Ruquest請求。 2. 環境被建立後,應用程式會透過m… Read More
    • [C#] 如何建立XML CDATA元素 摘要:C#如何建立XML CDATA元素 在與其他產品或服務Web services做溝通時,常常都會使用XML做資料交換的格式 最近遇到一個很特殊的案例,對方希望在傳過去的XML內容包兩層,第二層外面Tag要加上<![CDATA[" XML內容 "]]> XML文字內容只要被<![CDATA[和]]>包在裡面的,XML解析器在解析時就不會去解析裡面的內容,這樣的文字稱為Character Data … Read More
    • [.NET] ASP.NET 狀態管理(State Management):Session Session 狀態支援數種不同的資料儲存選項,簡單描述 Session 可用的狀態模式 InProc:存在Web伺服器的記憶體中;ASP.NET中預設的Session狀態設定,是最常用也是最方便的 Session 狀態模式,缺點是如果重新啟動伺服器,所有的Session資料將會遺失。 StateServer:儲存在 ASP.NET 狀態服務的處理序中;可以確保 Session 在 Web 應用程式重新啟動時保留下來,並且讓 Web 伺服陣… Read More
    • [IIS] 如何在 Windows 10 Pro 安裝 IIS 前言 最近有幸拿到公司配的新筆電,發現筆電上除了Visual Studio與SQL Server其他常用的都未安裝 難得有重新IIS站台的機會,雖然不難但最近初老症狀有點嚴重(?,這裡簡單紀錄一下IIS安裝過程 安裝過程 Control > Programs > Turn Windows features on or off Internet Information Services 項目打勾 展開 Internet Inform… Read More

    0 意見:

    張貼留言

    Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com