https://docs.microsoft.com/zh-cn/dotnet/standard/parallel-programming/dataflow-task-parallel-library

(一)源和目标
TPL数据流库包括数据流块,它是缓冲并处理数据的数据结构。TPL 定义了三种数据流块:源块、目标块和传播器块。
源块(System.Threading.Tasks.Dataflow.ISourceBlock<TOutput>)作为数据源,可以读取。
目标块(System.Threading.Tasks.Dataflow.ITargetBlock<TInput>)作为数据接收方,可以写入。
传播器块IPropagatorBlock<TInput,TOutput>)作为源块和目标块,可以读取和写入。

(二)连接块[ISourceBlock<TOutput>.LinkTo()]
可以连接数据流块来形成管道(这是数据流块的线性序列),或网络(这是数据流块的图形)。管道是网络的一种形式。 在管道或网络中,当数据可用时源向目标异步传播数据。 ISourceBlock<TOutput>.LinkTo()方法将源数据流块链接到目标块。 源可以链接到零个或多个目标;目标可以从零个或多个源进行链接。您可以同时向管道或网络中添加或从其移除数据流块。 预定义的数据流块类型处理所有的建立或释放链接的线程安全性。

(三)ActionBlock
ActionBlock实现ITargetBlock,说明它是消费数据的,也就是对输入的一些数据进行处理。它在构造函数中,允许输入一个委托,来对每一个进来的数据进行一些操作。如果使用Action(T)委托,那说明每一个数据的处理完成需要等待这个委托方法结束,如果使用了Func<TInput, Task>)来构造的话,那么数据的结束将不是委托的返回,而是Task的结束。默认情况下,ActionBlock会FIFO的处理每一个数据,而且一次只能处理一个数据,一个处理完了再处理第二个,但也可以通过配置来并行的执行多个数据。ActionBlock是顺序处理数据的,这也是ActionBlock一大特性之一。主线程在往ActionBlock中Post数据以后马上返回,具体数据的处理是另外一个线程来做的。数据是异步处理的,但处理本身是同步的,这样在一定程度上保证数据处理的准确性。

image

3.1 ActionBlock同步处理示例

class Program{ static ActionBlock<string> actionBlock = new ActionBlock<string>(Print); static void Main(string[] args) { TestSync(); Console.ReadKey(); } public static void TestSync() { for (int i = 0; i < 10; i++) { actionBlock.Post(i.ToString()); } Console.WriteLine("Post finished"); } public static void Print(string str) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} Tid:{Thread.CurrentThread.ManagedThreadId} 长度:{actionBlock.InputCount} 【{str}】"); }

}

image

3.2  ActionBlock异步处理示例

class Program{ static ActionBlock<string> actionBlock = new ActionBlock<string>(Print1); static void Main(string[] args) { TestSync(); Console.ReadKey(); } public static void TestSync() { for (int i = 0; i < 10; i++) { actionBlock.Post(i.ToString()); } Console.WriteLine("Post finished"); } public static async Task Print1(string str) { await Task.Delay(1000); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} Tid:{Thread.CurrentThread.ManagedThreadId} 长度:{actionBlock.InputCount} 【{str}】"); }}

image

①:以上异步基于构造函数:public ActionBlock(Func<TInput, Task> action);

②:可以用匿名异步函数来写

static ActionBlock<string> actionBlock = new ActionBlock<string>(async (str) => { await Task.Delay(1000); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} Tid:{Thread.CurrentThread.ManagedThreadId} 长度:{actionBlock.InputCount} 【{str}】");});

3.3  指定处理器个数
如果你想异步处理多个消息的话,ActionBlock也提供了一些接口,让你轻松实现。在ActionBlock的构造函数中,可以提供一个ExecutionDataflowBlockOptions的类型,让你定义ActionBlock的执行选项,在下面了例子中,我们定义了MaxDegreeOfParallelism选项,设置为3。目的的让ActionBlock中的Item最多可以3个并行处理。

public ActionBlock(Action<TInput> action, ExecutionDataflowBlockOptions dataflowBlockOptions);public ActionBlock(Func<TInput, Task> action, ExecutionDataflowBlockOptions dataflowBlockOptions);static ActionBlock<string> actionBlock = new ActionBlock<string>((str) => { Thread.Sleep(1000); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} Tid:{Thread.CurrentThread.ManagedThreadId} 长度:{actionBlock.InputCount} 【{str}】");

}, new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 3 });

static ActionBlock<string> actionBlock = new ActionBlock<string>(async (str) => { await Task.Delay(1000); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} Tid:{Thread.CurrentThread.ManagedThreadId} 长度:{actionBlock.InputCount} 【{str}】");}, new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 3 });

image

3.4 ActionBlock生命周期
       ActionBlock也有自己的生命周期,所有继承IDataflowBlock的类型都有Completion属性和Complete方法。调用Complete方法是让ActionBlock停止接收数据,而Completion属性则是一个Task,是在ActionBlock处理完所有数据时候会执行的任务,我们可以使用Completion.Wait()方法来等待ActionBlock完成所有的任务,Completion属性只有在设置了Complete方法后才会有效。

class Program{ static ActionBlock<string> actionBlock = new ActionBlock<string>((str) => { Thread.Sleep(1000); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} Tid:{Thread.CurrentThread.ManagedThreadId} 长度:{actionBlock.InputCount} 【{str}】"); }, new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = 3 }); static void Main(string[] args) { TestSync(); Console.ReadKey(); } public static void TestSync() { for (int i = 0; i < 10; i++) { actionBlock.Post(i.ToString()); } actionBlock.Complete(); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}【Post完成】"); actionBlock.Completion.Wait(); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}【队列处理完成】"); }}

image

posted @ 2021-01-05 17:39 李华丽 阅读(1824) 评论(1) 推荐(0) 编辑
摘要: DisQ 介绍 {以下是 Gitee 平台说明,您可以替换此简介 Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请 阅读全文
posted @ 2022-05-06 10:55 李华丽 阅读(455) 评论(0) 推荐(0) 编辑
摘要: DisQ Description {When you're done, you can delete the content in this README and update the file with details for others getting started with your re 阅读全文
posted @ 2022-05-06 10:23 李华丽 阅读(485) 评论(0) 推荐(0) 编辑
摘要: 阅读全文
posted @ 2022-05-05 13:32 李华丽 阅读(15) 评论(0) 推荐(0) 编辑
摘要: 有如下版本日志 创建分支提交后的版本日志如下 在dev1分支上进行合并操作git merge master,此时将master的两个提交d3,36放到dev指向的8cc48ec(HEAD)后面。此时d405874有两个子节点。同时生成一个合并的786dc72作为两个分支HEAD指向的子节点, 即78 阅读全文
posted @ 2022-04-27 22:34 李华丽 阅读(118) 评论(0) 推荐(0) 编辑
摘要: git diff –cached diff --git a/supervisord.log b/supervisord.log index 5394c6a..5c267c6 100644 a/supervisord.log +++ b/supervisord.log @@ -29,3 +29,23 阅读全文
posted @ 2022-04-26 09:26 李华丽 阅读(39) 评论(0) 推荐(0) 编辑
摘要: 2222222222222 阅读全文
posted @ 2022-04-22 16:49 李华丽 阅读(27) 评论(0) 推荐(0) 编辑
摘要: https://blog.csdn.net/weixin_39934085/article/details/110200848 阅读全文
posted @ 2022-04-14 11:05 李华丽 阅读(22) 评论(0) 推荐(0) 编辑
摘要: 阅读全文
posted @ 2022-04-11 11:05 李华丽 阅读(32) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2022-02-23 15:37 李华丽 阅读(2) 评论(0) 推荐(0) 编辑
摘要: LINQ是一种拉取模式,在查询过程中数据项是被逐个拉取出来的。例如有IEnumerable<string>提供给我们字符串值。当迭代它时,并不知道每个迭代会花费多长时间。如果使用常规的foreach或其他的同步迭代构造方式,我们将阻塞线程直到得到下一个值,这可能导致整个处理非常慢。这种场景被称为“基 阅读全文
posted @ 2022-02-16 09:31 李华丽 阅读(136) 评论(1) 推荐(0) 编辑
摘要: https://www.cnblogs.com/zhao56/p/14809419.html 阅读全文
posted @ 2022-02-08 11:00 李华丽 阅读(412) 评论(0) 推荐(0) 编辑
摘要: https://www.cnblogs.com/williamjie/p/10768657.html 阅读全文
posted @ 2022-01-27 10:29 李华丽 阅读(18) 评论(0) 推荐(0) 编辑
摘要: 变量的使用 https://blog.csdn.net/qq_29603999/article/details/78245736 阅读全文
posted @ 2021-10-13 14:08 李华丽 阅读(30) 评论(0) 推荐(0) 编辑
摘要: https://blog.csdn.net/weixin_39842528/article/details/81144747 阅读全文
posted @ 2021-08-20 13:54 李华丽 阅读(49) 评论(0) 推荐(0) 编辑
摘要: (一).NET Core3.1 代码分析public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilde 阅读全文
posted @ 2021-08-05 11:59 李华丽 阅读(289) 评论(0) 推荐(0) 编辑
摘要: https://blog.csdn.net/byxdaz/article/details/77979114 阅读全文
posted @ 2021-08-03 13:42 李华丽 阅读(180) 评论(0) 推荐(0) 编辑
摘要: (一)基础菜单 (一)设置字体 阅读全文
posted @ 2021-07-30 10:56 李华丽 阅读(974) 评论(0) 推荐(0) 编辑
摘要: @echo off color 2e echo ___________________________________________________________ echo 设置默认的控制台前景和背景颜色(color)。 echo 指定控制台输出的颜色属性 echo 颜色属性由两个十六进制数字指 阅读全文
posted @ 2021-07-21 16:37 李华丽 阅读(107) 评论(0) 推荐(0) 编辑
摘要: https://blog.csdn.net/zorro_jin/article/details/84927408 阅读全文
posted @ 2021-07-16 10:51 李华丽 阅读(20) 评论(0) 推荐(0) 编辑
摘要: (一)设置网络跃点数 ffff 阅读全文
posted @ 2021-07-06 10:59 李华丽 阅读(1602) 评论(0) 推荐(0) 编辑
摘要: https://blog.csdn.net/byxdaz/article/details/77979114 阅读全文
posted @ 2021-07-05 18:02 李华丽 阅读(69) 评论(0) 推荐(0) 编辑
摘要: MemoryCache缓存时间不精确问题 阅读全文
posted @ 2021-06-21 09:32 李华丽 阅读(83) 评论(0) 推荐(0) 编辑
摘要: 阅读全文
posted @ 2021-06-08 09:40 李华丽 阅读(526) 评论(0) 推荐(0) 编辑
摘要: https://www.cnblogs.com/chzbgb/p/kamino.html 阅读全文
posted @ 2021-06-03 14:15 李华丽 阅读(30) 评论(0) 推荐(0) 编辑
摘要: 阅读全文
posted @ 2021-05-31 12:00 李华丽 阅读(53) 评论(0) 推荐(0) 编辑
AmazingCounters.com
点击右上角即可分享
微信分享提示