作为单体程序,依赖的第三方服务虽不多,但是2C的程序还是有不少内容可讲;作为一个常规互联网系统,无外乎就是接受请求、处理请求,输出响应。

由于业务渐渐增长,数据处理的过程会越来越复杂和冗长,【连贯高效的处理数据】 越来越被看重,  .Net 提供了TPL  Dataflow组件使我们更高效的实现基于数据流和 流水线操作的代码

下图是单体程序中 数据处理的用例图。

程序中用到的TPL Dataflow 组件,Dataflow是微软前几年给出的数据处理库, 是由不同的处理块组成,可将这些块组装成一个处理管道,"块"对应处理管道中的"阶段", 可类比AspNetCore 中Middleware 和pipeline.。

  • TPL Dataflow库为消息传递和并行化CPU密集型和I / O密集型应用程序提供了编程基础,这些应用程序具有高吞吐量和低延迟。它还可以让您明确控制数据的缓冲方式并在系统中移动。

  • 为了更好地理解数据流编程模型,请考虑从磁盘异步加载图像并创建这些图像的应用程序。

    • 传统的编程模型通常使用回调和同步对象(如锁)来协调任务和访问共享数据, 从宏观看传统模型:任务是一步步紧接着完成的

    • 通过使用数据流编程模型,您可以创建在从磁盘读取图像时处理图像的数据流对象。在数据流模型下,您可以声明数据在可用时的处理方式以及数据之间的依赖关系。由于运行时管理数据之间的依赖关系,因此通常可以避免同步访问共享数据的要求。此外,由于运行时调度基于数据的异步到达而工作,因此数据流可以通过有效地管理底层线程来提高响应性和吞吐量。    也就是说: 你定义的是任务内容和任务之间的依赖,不关注数据什么时候流到这个任务 。

  • 需要注意的是:TPL Dataflow 非分布式数据流,消息在进程内传递,   使用nuget引用 System.Threading.Tasks.Dataflow 包。

TPL Dataflow 核心概念

1.  Buffer & Block

TPL Dataflow 内置的Block覆盖了常见的应用场景,当然如果内置块不能满足你的要求,你也可以自定“块”。

Block可以划分为下面3类:

  • Buffering Only    【Buffer不是缓存Cache的概念, 而是一个缓冲区的概念】

  • Execution

  • Grouping

使用以上块混搭处理管道, 大多数的块都会执行一个操作,有些时候需要将消息分发到不同Block,这时可使用特殊类型的缓冲块给管道“”分叉”。

2. Execution Block

  可执行的块有两个核心组件:

  • 输入、输出消息的缓冲区(一般称为Input,Output队列)

  • 在消息上执行动作的委托

  消息在输入和输出时能够被缓冲:当Func委托的运行速度比输入的消息速度慢时,后续消息将在到达时进行缓冲;当下一个块的输入缓冲区中没有容量时,将在输出时缓冲。

每个块我们可以配置:

  • 缓冲区的总容量, 默认无上限

  • 执行操作委托的并发度, 默认情况下块按照顺序处理消息,一次一个。

我们将块链接在一起形成一个处理管道,生产者将消息推向管道。

TPL Dataflow有一个基于pull的机制(使用Receive和TryReceive方法),但我们将在管道中使用块连接和推送机制。

  • TransformBlock(Execution category)-- 由输入输出缓冲区和一个Func<TInput, TOutput>委托组成,消费的每个消息,都会输出另外一个,你可以使用这个Block去执行输入消息的转换,或者转发输出的消息到另外一个Block。

  • TransformManyBlock (Execution category) -- 由输入输出缓冲区和一个Func<TInput, IEnumerable<TOutput>>委托组成, 它为输入的每个消息输出一个 IEnumerable<TOutput>

  • BroadcastBlock (Buffering category)-- 由只容纳1个消息的缓冲区和Func<T, T>委托组成。缓冲区被每个新传入的消息所覆盖,委托仅仅为了让你控制怎样克隆这个消息,不做消息转换。

            该块可以链接到多个块(管道的分叉),虽然它一次只缓冲一条消息,但它一定会在该消息被覆盖之前将该消息转发到链接块(链接块还有缓冲区)。

  • ActionBlock (Execution category)-- 由缓冲区和Action<T>委托组成,他们一般是管道的结尾,他们不再给其他块转发消息,他们只会处理输入的消息。

  • BatchBlock (Grouping category)-- 告诉它你想要的每个批处理的大小,它将累积消息,直到它达到那个大小,然后将它作为一组消息转发到下一个块。

  还有一下其他的Block类型:BufferBlock、WriteOnceBlock、JoinBlock、BatchedJoinBlock,我们暂时不会深入。

3. Pipeline Chain React

  当输入缓冲区达到上限容量,为其供货的上游块的输出缓冲区将开始填充,当输出缓冲区已满时,该块必须暂停处理,直到缓冲区有空间,这意味着一个Block的处理瓶颈可能导致所有前面的块的缓冲区被填满。

  但是不是所有的块变满时,都会暂停,BroadcastBlock 有允许1个消息的缓冲区,每个消息都会被覆盖, 因此如果这个广播块不能将消息转发到下游,则在下个消息到达的时候消息将丢失,这在某种意义上是一种限流(比较生硬).

编程实践

  将按照上图实现TPL Dataflow

①  定义Dataflow  pipeline

  上述程序在部署时就遇到相关的坑位,在测试环境_eqid2ModelTransformBlock 内Func委托稳定执行,程序并未出现异样;

  部署到生产之后, 该Pipeline会运行一段时间就停止工作,一直很困惑, 后来通过监测_eqid2ModelTransformBlock.Completion 属性,该块提前进入“完成态”   :   程序在执行某次Func委托时报错,Block提前进入完成态

TransfomrBlock.Completion 一个Task对象,当TPL Dataflow不再处理消息并且能保证不再处理消息的时候,就被定义为完成态, Task对象的TaskStatus枚举值将标记此Block进入完成态的真实原因

- TaskStatus.RanToCompletion       根据Block定义的任务成功完成

- TaskStatus.Fault                            因为未处理的异常 导致"过早的完成"

- TaskStatus.Cancled                       因为取消操作 导致 "过早的完成"

  我们需要小心处理异常, 一般情况下我们使用try、catch包含所有的执行代码以确保所有的异常都被处理。

  可将TPL Dataflow 做为进程内消息队列,本文只是一个入门参考,更多复杂用法还是看官网, 你需要记住的是, 这是一个.Net 进程内数据流组件, 能让你专注于流程。

原文地址:https://www.cnblogs.com/JulianHuang/p/11177766.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

TPL Dataflow .Net 数据流组件,了解一下?相关推荐

  1. TPL Dataflow .Net 数据流组件,了解一下?

    回顾上文 作为单体程序,依赖的第三方服务虽不多,但是2C的程序还是有不少内容可讲: 作为一个常规互联网系统,无外乎就是接受请求.处理请求,输出响应. 由于业务渐渐增长,数据处理的过程会越来越复杂和冗长 ...

  2. TPL Dataflow组件应对高并发,低延迟要求

    长话短说 2C互联网业务增长,单机多核的共享内存模式带来的排障问题.编程困难:随着多核时代和分布式系统的到来,共享模型已经不太适合并发编程,因此actor-based模型又重新受到了人们的重视. -- ...

  3. 为SSIS编写自定义数据流组件(DataFlow Component)之进阶篇:自定义编辑器

    我们之前几篇讨论过自定义数据流组件的一些技术,分别如下 入门篇 http://www.cnblogs.com/chenxizhang/archive/2009/06/20/1507467.html 数 ...

  4. TPL Dataflow库的几个扩展函数

    TPL Dataflow是微软面向高并发应用而推出的新程序库.借助于异步消息传递与管道,它可以提供比线程池更好的控制.本身TPL库在DataflowBlock类中提供了不少扩展函数,用起来还是非常方便 ...

  5. 在.net 4.0程序中使用TPL Dataflow

    今天写了一个小程序,用到了TPL Dataflow,结果在部署的时候发现了一个问题:客户的服务器中有win2003的机器,2003是不支持.net 4.5的,但TPL Dataflow却只能在.net ...

  6. Differential dataflow 微分数据流

    微分数据流: 本文为翻译文章 摘要: 现有的用于处理不断变化的输入数据的计算模型,除了在有限的特殊情况下,无法有效地支持迭代查询.这使得复杂的任务执行起来很困难, 例如在交互的时间尺度上对变化的数据进 ...

  7. .Net Core中利用TPL(任务并行库)构建Pipeline处理Dataflow

    在学习的过程中,看一些一线的技术文档很吃力,而且考虑到国内那些技术牛人英语都不差的,要向他们看齐,所以每天下班都在疯狂地背单词,博客有些日子没有更新了,见谅见谅 什么是TPL? Task Parall ...

  8. 三分钟总览微软任务并行库TPL

    点击上方蓝字进行关注 有小伙伴问我每天忽悠的TPL是什么? ☹️ 这次站位高一点,严肃讲一讲. 引言 俗话说,不想开飞机的程序员不是一名好爸爸:作为微软技术栈的老鸟,一直将代码整洁之道奉为经典, 优秀 ...

  9. 像Labview一样,使用C#构建测量数据流式处理框架

    1. C# DataFlow介绍 介绍部分参考博客:TPL DataFlow初探(一) 侵权请联系删除 官方解释: TPL(任务并行库) 数据流库向具有高吞吐量和低滞后时间的占用大量 CPU 和 I/ ...

最新文章

  1. 英文求职信计算机网络,计算机网络专业毕业生英文求职信.doc
  2. HDU 3062 Party(2-sat题模板+tarjan )
  3. java访问其它服务器,一个Java Web应用程序是否可以在tomcat服务器的同一本地主机中调用另一个Java Web应用程序...
  4. typora使用pandoc导出功能
  5. Linux 端口- PID - 启动目录
  6. 你是如何抵制百度系列产品的?
  7. 苹果核 - iOS端Mock GPS定位 —— 测试、开发、玩游戏、发朋友圈等等,你都用得上...
  8. 智能信息处理专业是干嘛的?
  9. 适合matlab的编程字体“YAHEI CONSOLAS HYBRID”-下载+安装
  10. ios java模拟器 2017_Visual Studio 2017(Xamarin)未显示iPhone模拟器列表
  11. 电子书资源(建议珍藏,不断更新中)
  12. matlab电影,如何制作电影(与matlab相关)?
  13. 安装 配置 Nginx
  14. JAVAEE 实训日志01_20200704 上
  15. Interacting Attention Graph for Single Image Two-Hand Reconstruction(单幅图像双手重建的交互注意图)
  16. UVM通信篇之五:TLM2通信
  17. Android应用构建:8:使用keytool确认证书与私钥信息
  18. 【2022最新爬虫】JS逆向之采集某某海关进出口信用平台数据
  19. 一篇带你走进程序设计的准则——DAO和MVC设计模式
  20. python爬虫分布图_13天搞定Python分布爬虫!成为炙手可热的爬虫工程师

热门文章

  1. dreambackend.java_【AndroidTV】如何自定义屏保、更改屏保时长
  2. kali linux超级用户_如何优雅的在Linux上使用Powershell]
  3. 谷歌云使用账号密码_如何使用Google密码检查
  4. 黑客攻防:从入门到入狱_每日新闻摘要:游戏服务黑客被判入狱27个月
  5. 禁用windows10更新_如何在Windows 10中禁用投影
  6. mysql 面试知识点笔记(七)RR如何避免幻读及非阻塞读、范式
  7. Java之品优购课程讲义_day20(5)
  8. 详解用65行javascript代码做Flappy Bird
  9. 使用ArcGIS Server发布我们的数据
  10. SegmentFault 创始人祁宁对话 C# 之父 Anders Hejlsberg