持久任务框架 (DTF) 是基于async/await 工作流执行框架。工作流的解决方案很多,包括Windows Workflow Foundation,BizTalk,Logic Apps, Workflow-CoreElsa-Core。最近我在Dapr 的仓库里跟踪工作流构建块的进展,DTFx 正好是.NET开发的,所以对他多了几分关注,以前没有深入进去看看,现在我觉得是值得推荐给大家的一个工作流方案,它足够轻量级,而且非常简单,依赖很少。

持久任务框架是一个开源框架,它为 .NET 平台中的工作流即代码提供了基础。GitHub上:https://github.com/Azure/durabletask

它有两个主要组件:业务流程和任务。业务流程“编排”应用程序逻辑,以内联方式执行自定义代码并调用任务。自定义业务流程派生自 TaskOrchestration<TResult, TInput>自定义任务派生自 TaskActivity<TInput, TResult>。

推荐大家从这两个仓库可用来学习和生产使用。

Microsoft.Extensions.Hosting包装器: https://github.com/jviau/durabletask-hosting

持久任务框架扩展: https://github.com/lucaslorentz/durabletask-extensions

我们一起来看下持久任务框架的Hello world: 代码来自https://github.com/jviau/durabletask-hosting 的 DurableTask.Samples:

这个非常简单的业务流程“GreetingsOrchestration”,有两个称为任务“GetUserTask”,它执行名称提示和“SendGreetingTask”,它将问候语写入控制台。

GreetingsOrchestration 派生自 TaskOrchestration<string、string> 并具有调用 GetUserTask 和 SendGreetingTask 的 RunTask 方法。

using DurableTask.Core;

namespace DurableTask.Samples.Greetings;

/// <summary>

/// A task orchestration for greeting a user.

/// </summary>

public class GreetingsOrchestration : TaskOrchestration<string, string>

{
     /// <inheritdoc />
     public override async Task<string> RunTask(OrchestrationContext context, string input)
     {
         string user = await context.ScheduleTask<string>(typeof(GetUserTask));
         string greeting = await context.ScheduleTask<string>(typeof(SendGreetingTask), user);
         return greeting;
     }

}

GetUserTask 派生自 TaskActivity<string,string> 并实现了 Execute 方法

using DurableTask.Core;

namespace DurableTask.Samples.Greetings;

/// <summary>

/// A task activity for getting a username from console.

/// </summary>

public class GetUserTask : TaskActivity<string, string>

{
     private readonly IConsole _console;

/// <summary>
     /// Initializes a new instance of the <see cref="GetUserTask"/> class.
     /// </summary>
     /// <param name="console">The console output helper.</param>
     public GetUserTask(IConsole console)
     {
         _console = console ?? throw new ArgumentNullException(nameof(console));
     }

/// <inheritdoc />
     protected override string Execute(TaskContext context, string input)
     {
         _console.WriteLine("Please enter your name:");
         return _console.ReadLine();
     }

}

SendGreetingTask 派生自 TaskActivity<string、string> 并实现了 Excute 方法

using DurableTask.Core;

namespace DurableTask.Samples.Greetings;

/// <summary>

/// A task for sending a greeting.

/// </summary>

public sealed class SendGreetingTask : AsyncTaskActivity<string, string>

{
     private readonly IConsole _console;

/// <summary>
     /// Initializes a new instance of the <see cref="SendGreetingTask"/> class.
     /// </summary>
     /// <param name="console">The console output helper.</param>
     public SendGreetingTask(IConsole console)
     {
         _console = console ?? throw new ArgumentNullException(nameof(console));
     }

/// <inheritdoc />
     protected override async Task<string> ExecuteAsync(TaskContext context, string user)
     {
         string message;
         if (!string.IsNullOrWhiteSpace(user) && user.Equals("TimedOut"))
         {
             message = "GetUser Timed out!!!";
             _console.WriteLine(message);
         }
         else
         {
             _console.WriteLine("Sending greetings to user: " + user + "...");
             await Task.Delay(5 * 1000);
             message = "Greeting sent to " + user;
             _console.WriteLine(message);
         }

return message;
     }

}

上面的这个例子非常基础,我们在项目中要把它用起来就要用到这个扩展项目 https://github.com/lucaslorentz/durabletask-extensions。这个项目通过更多功能扩展持久任务框架,并使其更易于使用,目前还在开发过程中,尚未达到投入生产的程度。包含了下列这些功能,让你在任何地方都可以运行。

  • 更多定义存储功能的接口
  • 依赖注入集成
  • EF Core MySql/PostgreSQL/SqlServer storages
  • 分布式工作线程:允许在多个工作线程中拆分业务流程/活动实现
  • 通过 GRPC 协议进行间接存储访问:将您的存储选择和配置集中在单个组件中。
  • 用户界面
  • BPMN 运行器

示例文件夹中,您可以找到经典书籍《飞行、汽车、酒店》的实现,其中包含补偿问题。

该示例旨在演示具有以下组件的微服务体系结构:

  • 服务器:连接到存储并将其公开为 GRPC 终结点。
  • 应用程序接口:公开 REST API 以管理业务流程。
  • 用户界面:公开用于管理业务流程的 UI。
  • 业务流程工作线程:为给定问题实现BookParallelBookSquential业务流程。
  • 飞行工作人员:实施预订航班和取消航班活动。
  • 车夫:实施“预订汽车”和“取消汽车”活动。
  • 酒店工作人员:实施预订酒店和取消酒店活动。
  • BPMNWorker:一个建立在持久任务之上的实验性 BPMN 运行器。对于给定的问题,还有BookParallelBookSequentialBPMN 工作流。

使用c#的 async/await编写 长时间运行的基于代码的工作流的 持久任务框架的更多相关文章

  1. JavaScript 如何工作的: 事件循环和异步编程的崛起 + 5 个关于如何使用 async/await 编写更好的技巧

    原文地址:How JavaScript works: Event loop and the rise of Async programming + 5 ways to better coding wi ...

  2. [ASP.NET Core 3框架揭秘] 服务承载系统[1]: 承载长时间运行的服务[上篇]

    借助.NET Core提供的承载(Hosting)系统,我们可以将任意一个或者多个长时间运行(Long-Running)的服务寄宿或者承载于托管进程中.ASP.NET Core应用仅仅是该承载系统的一 ...

  3. 三点经验:长时间运行函数需要随时发射信号报告进度,以及设置bool变量随时可以退出,每做一步操作必须及时记录和处理相关信息

    三点经验:长时间运行函数需要随时发射信号报告进度,以及设置bool变量随时可以退出,每做一步操作必须及时记录和处理相关信息 不能到最后一起处理,否则万一中间出错了,这个记录状态就全部都乱了.

  4. 定时器解决js长时间运行脚本问题

    一般地,单个js操作的运行时间不应超过100毫秒,否则的话,会影响用户体验,用户会认为自己与界面失去联系.而对于一些复杂的任务,可能无法在100ms内完成,甚至会突破浏览器限制(调用栈大小限制和长时间 ...

  5. ASP.NET 工作流:支持长时间运行操作的 Web 应用程序

    ASP.NET 工作流 支持长时间运行操作的 Web 应用程序 Michael Kennedy   代码下载位置:MSDN 代码库 在线浏览代码 本文将介绍以下内容: 独立于进程的工作流 同步和异步活 ...

  6. hadoop如何处理长时间运行不完成的map/reduce 任务?

    如果某一个任务在某个节点上长时间不完成,怎么手动干预来处理这种情况?董西成博客上找到的回答:hadoop中有三种特殊的任务,failed task,killed task和speculative ta ...

  7. jetty 长时间运行之后出现 PWC6117 file not found

    严重: PWC6117: File "%2Ftmp%2Fjetty-0.0.0.0-9090-admin.war-_admin-any-%2Fwebapp%2Ferror%2F404.jsp ...

  8. hadoop长时间运行后,stop-all.sh报错

    报错现象: hadoop在stop-all.sh的时候依据的是datanode上的mapred和dfs进程号. 而默认的进程号保存在/tmp下,linux默认会每 隔一段时间(一般是一个月或者7天左右 ...

  9. Oracle11g 查询长时间运行的SQL

    一.大量的查询 某些时候,因为SQL的问题,导致数据库的session大量积压,服务器的磁盘读增大,CPU使用率剧增.一般这种SQL,都是一些全表扫描.多表关联.报表或者排序类的SQL.这中情况很有可 ...

  10. Android 长时间运行任务说明

    android 4.0 后,小米手机需要授权 自动启动 (在安全中心权限里设置),不然AlarmManager设置系统闹钟将不起作用

随机推荐

  1. 高可用代理服务器实现keepalive+squid

    〇.前言 之前单机部署了squid代理服务器,现在实现一下高可用. 还有自定义squid的error页面 准备:两台centos7(1C2GB) ​ 三个可用IP,一主一备一虚拟IP(VIP) 一.安 ...

  2. Fast.Framework ORM 于中秋节后 正式开源

    Fast Framework 作者 Mr-zhong 开源项目地址 https://github.com/China-Mr-zhong/Fast.Framework QQ交流群 954866406 欢 ...

  3. 快速排序C语言版图文详解

    ​ 算法原理:选一个数位基准,将序列分成两个部分,一边全是比它小序列,另一边全是比它大序列.然后再分别对比他小的序列和比再次进行基准分割.依次分割下去,得到一个有序的队列. 原理图示: ​编辑 ​编辑 ...

  4. Jmeter中的JSON提取器用法

    一.使用前提 一般来说JSON提取器只适用于响应结果中返回的是json数据 二.需求 在下一个接口调用上一个接口的数据,如:请求1返回的结果,处理以后作为请求2的参数使用. 首先需要下载JSON Ex ...

  5. Lua CallbackHell优化

    概述 在异步操作中,常常要使用回调.但是,回调的嵌套常常会导致逻辑混乱,一步错步步错,难以维护.在Lua中,可以使用协程进行优化. 问题分析 模拟一个回合制游戏攻击过程 local function ...

  6. Java内部类初探

    Java内部类初探 之前对内部类的概念不太清晰,在此对内部类与外部类之间的关系以及它们之间的调用方式进行一个总结. Java内部类一般可以分为以下三种: 成员内部类 静态内部类 匿名内部类 一.成员内 ...

  7. 使用ingress-nginx

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247496824&idx=1&sn=cd845d77 ...

  8. 从Spring Cloud微服务视角理解Kubernetes

  9. .NET 反向代理 YARP 代理 GRPC

    前面的 YARP 文档中,介绍了怎么去代理 http,和如何根据域名转发,而在现在微服务的应用是越来越来多了,服务间的调用依靠 http 越来越不现实了,因为 http 多次握手的耗时越发的影响应用的 ...

  10. 聊聊Linux中CPU上下文切换

    目录 什么是CPU上下文 CPU上下文切换 上一任务的CPU上下文保存在哪? 进程上下文切换 内核空间和用户空间 top命令查看CPU资源 系统调用 进程上下文切换 和 系统调用的区别? 进程切换的常 ...