dotnet 推薦 LightWorkFlowManager 輕量的工作過程管理庫

来源:https://www.cnblogs.com/lindexi/archive/2023/10/09/17750753.html
-Advertisement-
Play Games

本以為跟國際化無緣,不在軟體的考慮範圍內,沒想到偶爾一個項目還是繞不開,小記一下System.Globalization.CultureInfo.InstalledUICulture.Name 這是獲得英文的區域碼,也就是zh-cn的這種,需要找區域碼字典對照。 System.Globalizati ...


本文將和大家推薦我團隊開源的 LightWorkFlowManager 輕量的工作過程管理庫,適合任何需要執行工作過程的應用邏輯,可以方便將多個工作過程拼湊起來,且自動集成重試和失敗處理,以及日誌和上報功能

這個 LightWorkFlowManager 輕量的工作過程管理庫是我所在的團隊在 GitHub 上使用最友好的 MIT 協議開源的庫,請看 https://github.com/dotnet-campus/LightWorkFlowManager

這個 LightWorkFlowManager 輕量的工作過程管理庫現在已經在我團隊的正式產品應用上運行有半年了,相對來說比較穩定。使用過程中如果有任何問題,都歡迎在 GitHub 上新建 Issues 進行反饋

世界上有許多現有的工作過程管理,那為什麼還重新造了一個?沒啥原因,自己造的用的順手。這個 LightWorkFlowManager 庫在功能上和其他的工作過程管理庫相比要缺失許多,但勝在輕量。且 LightWorkFlowManager 最重要的賣點就是對調試友好,適合用在本身複雜度就比較好的邏輯情況下,可以有效降低引入工作過程管理模塊本身帶來的額外複雜度

許多現有的功能齊全的工作過程管理庫都是在 ASP.NET Core 上使用的。然而我這裡的需求是在客戶端應用框架上使用,且大部分情況下是在用戶的設備上運行的,許多服務依賴本身是不存在的。儘管許多現有的功能齊全的工作過程管理庫都可以通過配置的形式將其切換到單機內運行,然而這樣做將在大部分時候不是庫的推薦用法,用起來沒有那麼順。為此我所在的團隊開發了 LightWorkFlowManager 輕量的工作過程管理庫,這個庫可以很方便在客戶端框架上運行,比如在 WPF 應用程式、在 MAUI 應用程式上運行。同時 LightWorkFlowManager 也兼顧 ASP.NET Core 服務本身,特別是依賴註入部分,可以和預設的服務的依賴註入相連接

以下是 LightWorkFlowManager 輕量的工作過程管理庫的使用方法

按照 dotnet 的慣例,先安裝 NuGet 庫,請看 https://www.nuget.org/packages/dotnetCampus.LightWorkFlowManager

在開始介紹使用方法之前,需要先介紹一下 LightWorkFlowManager 裡面的概念。在 LightWorkFlowManager 裡面定義了 MessageWorkerManager 類型,將其作為工作器的管理器,用途就是將各個工作器串聯起來,且運行起來,這個 MessageWorkerManager 就是 LightWorkFlowManager 的入口類型

在 LightWorkFlowManager 裡面定義了工作器的基礎類型就是 MessageWorker 類型,所有的業務上的開發者自定義的工作器都需要直接或間接繼承 MessageWorker 類型

瞭解基礎概念之後,接下來就開始編寫一個簡單的邏輯作為例子

使用方法

1、 創建 MessageWorkerManager 對象。創建 MessageWorkerManager 工作器管理器即可作為承載工作器的框架,請為每次單獨的任務創建獨立的 MessageWorkerManager 對象

            // 每個任務一個 TaskId 號
            string taskId = Guid.NewGuid().ToString();
            // 相同類型的任務採用相同的名字,比如這是做 PPT 解析的任務
            string taskName = "PPT 解析";
            // 提供容器
            IServiceScope serviceScope = serviceProvider.CreateScope();

            var workerManager = new MessageWorkerManager(taskId, taskName, serviceScope);

2、 定義 Worker 工作器。以下例子代碼定義了模擬業務代碼的 FooWorker 工作器,可以在 FooWorker 重寫的 DoInnerAsync 方法裡面編寫執行的業務代碼。以下代碼的 InputType 和 OutputType 分別是工作器的輸入和輸出類型,每個工作器的輸出對象都會自動加入到 MessageWorkerManager 的過程上下文緩存裡面

record InputType();

record OutputType();

class FooWorker : MessageWorker<InputType, OutputType>
{
    protected override ValueTask<WorkerResult<OutputType>> DoInnerAsync(InputType input)
    {
        ...
    }
}

3、 執行 Worker 工作器。 完成類型的定義之後,接下來演示如何通過 MessageWorkerManager 將 FooWorker 運行起來

            var result = await workerManager
                .GetWorker<FooWorker>()
                .RunAsync();

以上代碼也可以簡寫為以下代碼

            var result = await workerManager.RunWorker<FooWorker>();

以上代碼運行的前提是先註入 FooWorker 所需的 InputType 類型的對象。下文將告訴註入工作器參數部分的更多細節

機制和功能

工作器參數

工作器參數通過 MessageWorkerManager 工作器管理的 IWorkerContext 上下文讀取。每個工作器的可返回值類型都會自動被設置到 IWorkerContext 上下文裡面。如此即可自動實現上一個 Worker 的輸出作為下一個 Worker 的輸入

在每個工作器裡面,都可以通過 SetContext 設置上下文信息

在開始執行工作器時,還可以手動設置輸入參數,如以下例子

 // 例子1:先獲取工作器,再賦值給到工作器的執行方法

            await Manager
                .GetWorker<FooWorker>()
                .RunAsync(new InputType());

 // 例子2: 通過 SetContext 進行設置參數,再執行工作器
            await Manager
                .SetContext(new InputType())
                .RunWorker<FooWorker>();

如果有些工作器之間的輸入和輸出參數需要進行轉換,也可以 SetContext 傳入轉換委托進行參數轉換

 // 以下例子將當前上下文里的 Foo1Type 類型轉換為 FooWorker 需要的 Foo2Type 參數
           await Manager
                .SetContext((Foo1Type foo1) => ConvertFoo1ToFoo2(foo1))
                .RunWorker<FooWorker>();

異常中斷和重試

每個 Worker 都可以返回 WorkerResult 類型的返回值,可以在返回值裡面告知框架層是否當前的 Worker 執行成功。在執行失敗時,可以賦值錯誤碼,方便定位調試或輸出。在執行失敗時,可以返回告知框架層是否需要重試

中斷後續的工作器執行有兩個方法:

方法1: 通過返回狀態為失敗的 WorkerResult 返回值。一旦工作管理器的狀態為 IsFail 狀態,將會阻止所有的沒有標記 CanRunWhenFail 為 true 的工作器的執行。換句話說就是除了哪些不斷成功或失敗狀態都要執行的 Worker 工作器之外,其他的工作器都將不會執行,包括 SetContext 裡面的委托轉換也不會執行

方法2: 通過拋出異常的方式,通過 dotnet 裡面的異常可以讓後續邏輯炸掉不再執行

以上兩個方法都是框架推薦使用的。框架設計的偏好是如果在重視性能的情況下,儘量使用方法1的方式中斷執行。如果是在複雜的業務邏輯,有大量業務邏輯穿插在工作過程之外,則可以方便通過方法2進行中斷

在 Worker 里執行其他 Worker 工作器

在一個 Worker 裡面,可以執行其他的 Worker 工作器,如此可以比較自由的實現分支邏輯,套娃決定執行工作器

例子如下:

假定有一個 Worker2 工作器,定義如下:

    class Worker2 : MessageWorker<InputType, OutputType>
    {
        protected override ValueTask<WorkerResult<OutputType>> DoInnerAsync(InputType input)
        {
            return SuccessTask(new OutputType());
        }
    }

    record InputType();

    record OutputType();

有另一個 Worker1 工作器,可以在 Worker1 裡面執行 Worker2 工作器:

    class Worker1 : MessageWorkerBase
    {
        public override async ValueTask<WorkerResult> Do(IWorkerContext context)
        {
            await Manager
                .GetWorker<Worker2>()
                .RunAsync(new InputType());

            return WorkerResult.Success();
        }
    }

委托工作器

有一些非常小且輕的邏輯,也想加入到工作過程裡面,但不想為此定義一個單獨的工作器。可以試試委托工作器,如以下代碼例子

            var delegateMessageWorker = new DelegateMessageWorker(_ =>
            {
                // 在這裡編寫委托工作器的業務內容
            });

            var result = await messageWorkerManager.RunWorker(delegateMessageWorker);

如果連 DelegateMessageWorker 都不想創建,那也可以直接使用 MessageWorkerManager 的 RunWorker 方法傳入委托,如以下代碼例子

            await messageWorkerManager.RunWorker((IWorkerContext context) =>
            {
                // 在這裡編寫委托工作器的業務內容
            });

博客園博客只做備份,博客發佈就不再更新,如果想看最新博客,請到 https://blog.lindexi.com/

知識共用許可協議
本作品採用知識共用署名-非商業性使用-相同方式共用 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發佈,但務必保留文章署名[林德熙](https://www.cnblogs.com/lindexi)(包含鏈接:https://www.cnblogs.com/lindexi ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我[聯繫](mailto:[email protected])。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本節將向讀者介紹如何使用鍵盤滑鼠操控模擬技術,鍵盤滑鼠操控模擬技術是一種非常實用的技術,可以自動化執行一些重覆性的任務,提高工作效率,在Windows系統下,通過使用各種鍵盤滑鼠控制函數實現動態捕捉和模擬特定功能的操作。有時我們經常需要進行重覆性的滑鼠操作,例如繁瑣的點擊、拖拽。這些任務可能消耗大量... ...
  • 基於java應急救援物資管理系統設計與實現,可適用於java物資系統,java物資救援管理系統,springboot應急救援物資管理系統,java物資分配管理系統,javaWeb應急救援物資管理系統設計與實現,物資進銷存管理系統,物資入庫出庫管理系統,物資申領系統等等 ...
  • 9. 用Rust手把手編寫一個wmproxy(代理,內網穿透等), HTTP2改造篇之HPACK示例, 瞭解http2頭信息如何處理 項目 ++wmproxy++ gite: https://gitee.com/tickbh/wmproxy github: https://github.com/ti ...
  • 本次問題是想要拷貝文件夾,但是找了一圈發現只有File有Copy或者FileInfo的CopyTo,並沒有Directory的拷貝操作方法。 針對C#中拷貝文件夾的方法就是先生成一個目標文件夾(destinationFolder)再將(soursefolder)中的文件依次拷貝到目標文件夾中,C#並 ...
  • 客戶端: 在UGUI中創建兩個Button,一個是連接伺服器,一個是發送消息的按鈕,分別綁定Connection和SendMessage兩個函數 並且創建一個InputField和一個Text文本,Text文本用於顯示伺服器回傳的消息,InputField用於輸入要發送的消息 以下是代碼: 1 us ...
  • 異常捕獲 使用異常捕獲可以捕獲出現異常的代碼塊,防止因為異常拋出造成的程式卡死的情況發生。 try{}catch{}finally{}結構 //異常捕獲 try { string str=Console.ReadLine(); int i=int.Parse(str); Console.WriteL ...
  • 有些時候我們實現了某個功能, 但是僅僅通過有限的幾次調用無法知道這個功能的執行效率以及資源占用情況, 此時就可以使用 Benchmark 對這個功能進行基準測試 在 dotnet 中主要使用 BenchmarkDotNet BenchmarkDotNet 是一個.NET的基準測試框架, 主要用於測量 ...
  • 上篇文章講述了C#反射知識點,本文將介紹C#特性(Attribute)的知識點。C#特性(Attribute)是一種強大的元數據機制,用於為代碼元素(如類、方法、屬性等)添加信息,以影響它們的行為或提供額外的信息。本文將介紹C#特性每個.NET開發都應熟悉的知識點,希望對大家開發有一定的幫助。 1、 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...