C# 初识System.IO.Pipelines
写在前面
在进一步了解Socket粘包分包的过程中,了解到了.NET 中的 System.IO.Pipelines,可以更优雅高效的解决这个问题;先跟随官方的示例做个初步的认识。
System.IO.Pipelines 是一个库,旨在使在 .NET 中执行高性能 I/O 更加容易。 该库的目标为适用于所有 .NET 实现的 .NET Standard。
System.IO.Pipelines 具有高性能的流数据分析功能,可以减少代码复杂性。
老规矩通过NuGet安装该类库

代码实现
using System.Buffers;
using System.IO.Pipelines;
using System.Text;class Program
{static async Task Main(){using var stream = File.OpenRead("lorem-ipsum.txt");var reader = PipeReader.Create(stream);var writer = PipeWriter.Create(Console.OpenStandardOutput(),new StreamPipeWriterOptions(leaveOpen: true));WriteUserCancellationPrompt();var processMessagesTask = ProcessMessagesAsync(reader, writer);var userCanceled = false;var cancelProcessingTask = Task.Run(() =>{while (char.ToUpperInvariant(Console.ReadKey().KeyChar) != 'C'){WriteUserCancellationPrompt();}userCanceled = true;// No exceptions thrownreader.CancelPendingRead();writer.CancelPendingFlush();});await Task.WhenAny(cancelProcessingTask, processMessagesTask);Console.WriteLine($"\n\nProcessing {(userCanceled ? "cancelled" : "completed")}.\n");}static void WriteUserCancellationPrompt() =>Console.WriteLine("Press 'C' to cancel processing...\n");static async Task ProcessMessagesAsync(PipeReader reader,PipeWriter writer){try{while (true){ReadResult readResult = await reader.ReadAsync();ReadOnlySequence<byte> buffer = readResult.Buffer;try{if (readResult.IsCanceled){break;}if (TryParseLines(ref buffer, out string message)){FlushResult flushResult =await WriteMessagesAsync(writer, message);if (flushResult.IsCanceled || flushResult.IsCompleted){break;}}if (readResult.IsCompleted){if (!buffer.IsEmpty){throw new InvalidDataException("Incomplete message.");}break;}}finally{reader.AdvanceTo(buffer.Start, buffer.End);}}}catch (Exception ex){Console.Error.WriteLine(ex);}finally{await reader.CompleteAsync();await writer.CompleteAsync();}}static bool TryParseLines(ref ReadOnlySequence<byte> buffer,out string message){SequencePosition? position;StringBuilder outputMessage = new();while (true){position = buffer.PositionOf((byte)'\n');if (!position.HasValue)break;outputMessage.Append(Encoding.ASCII.GetString(buffer.Slice(buffer.Start, position.Value))).AppendLine();buffer = buffer.Slice(buffer.GetPosition(1, position.Value));};message = outputMessage.ToString();return message.Length != 0;}static ValueTask<FlushResult> WriteMessagesAsync(PipeWriter writer,string message) =>writer.WriteAsync(Encoding.ASCII.GetBytes(message));
}
调用示例

总结
例子中用到的文本文件是一个以\n 换行符作为结尾的多行文本,微软官方示例没有提供,这个是自己建的测试文件,如果没有检测到\n会抛出异常。

从运行的结果可以看到,从传入的流中识别以\n结尾,作为数据块的区分,利用这个特性定义数据报文的尾部,实现分包。
相关文章:
C# 初识System.IO.Pipelines
写在前面 在进一步了解Socket粘包分包的过程中,了解到了.NET 中的 System.IO.Pipelines,可以更优雅高效的解决这个问题;先跟随官方的示例做个初步的认识。 System.IO.Pipelines 是一个库,旨在使在 .NET 中执行高性能 I/O 更加容…...
嵌入式——RTC内置实时时钟
学习目标 理解原理图RTC设计部分掌握初始化RTC掌握设置时间掌握读取时间学习内容 RTC原理图 RTC结构框图 RTC时钟 开发流程 加载依赖。gd32f4xx_rtc.c,gd32f4xx_pmu.c初始化RTC。时钟配置。获取时钟。RTC初始化 // 电池管理加载 rcu_periph_clock_enable(RCU_PMU); pmu_back…...
nodejs微信小程序+python+PHP的热带野生动物园景点预约订票系统的设计与实现-计算机毕业设计推荐
目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…...
ASP.NET MVC的5种AuthorizationFilter
一、IAuthorizationFilter 所有的AuthorizationFilter实现了接口IAuthorizationFilter。如下面的代码片断所示,IAuthorizationFilter定义了一个OnAuthorization方法用于实现授权的操作。作为该方法的参数filterContext是一个表示授权上下文的AuthorizationContext对…...
C语言初学8:函数和作用域
一、函数 函数声明告诉编译器函数的名称、返回值类型和参数。在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。函数定义提供了函数的实际主体。...
2024年科技盛宴“上海智博会·上海软博会”招商工作接近尾声
2024年上海智博会和上海软博会即将于3月份在上海跨国采购会展中心盛大召开。作为全球科技和软件行业的盛会,这两大展会汇集了业界顶尖的企业、创新技术和前瞻思想,吸引了来自世界各地的专业人士和参展商。 今年的展会将一如既往地为大家呈现最前沿的科技…...
深圳锐科达SIP矿用电话模块SV-2801VP
深圳锐科达SIP矿用电话模块SV-2801VP 一、简介 SV-2800VP系列模块是我司设计研发的一款用于井下的矿用IP音频传输模块,可用此模块打造一套低延迟、高效率、高灵活和多扩展的IP矿用广播对讲系统,亦可对传统煤矿电话系统加装此模块,进行智能化…...
【Qt-数据库】
Qt编程指南 ■ SQLite■ CSV■ JSON ■ SQLite Qt 提供了很多操作数据库的类, SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于 250KiB。 SQLite 是一个进程内的库,实现了自给自足的、无…...
windows文件名命名规范(文件名规范、命名规则、避免特殊字符、注意文件名长度限制260个字符)
文章目录 Windows文件名命名规范1. 基本规则1.1 避免使用特殊字符1.2 限制文件名长度1.3 避免使用预留名称 2. 最佳实践2.1 使用描述性名称2.2 使用连字符或下划线代替空格2.3 使用日期和版本号 3. 实用技巧3.1 批量重命名文件3.2 使用PowerShell进行高级文件操作 Windows文件名…...
如何修改MySQL的默认端口
MySQL是世界上最流行的开源关系型数据库管理系统之一。在某些情况下,由于安全性、网络策略或端口冲突的原因,数据库管理员可能需要更改MySQL服务的默认监听端口。本文将指导您如何在不同的操作系统上更改MySQL的默认端口。 理解MySQL配置文件 MySQL的配…...
Android笔记(二十一):Room组件实现Android应用的持久化处理
一、Room组件概述 Room是Android JetPack架构组件之一,是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层,使之实现数据访问。 (1)实体类(Entity):映射并封装了数据库对应的数据表中…...
uniapp中各种状态的按钮
当涉及状态按钮时,UniApp提供了丰富的选择。UniApp中的状态按钮可以是开关按钮、单选按钮、多选按钮等。开发者可以根据具体需求选择使用合适的状态按钮组件。对于状态按钮,UniApp提供了丰富的API和事件,可以轻松实现状态切换、状态监听等功能…...
模式识别与机器学习-判别式分类器
模式识别与机器学习-判别式分类器 生成式模型和判别式模型的区别线性判别函数多分类情况多分类情况1多分类情况2多分类情况3 例题 广义线性判别函数实例 分段线性判别函数Fisher线性判别感知机算法例:感知机多类别分类 谨以此博客作为学习期间的记录 生成式模型和判…...
c++11 标准模板(STL)(std::pair)(七)访问 pair 的一个元素
定义于头文件 <utility> std::pair 是一个结构体模板,其可于一个单元存储两个相异对象。 pair 是 std::tuple 的拥有两个元素的特殊情况。 访问 pair 的一个元素 std::get(std::pair) template< size_t I, class T1, class T2 > typename std::tuple…...
IP 地址归属地查询
IP 地址归属地查询 1. IP 地址归属地查询2. IP 地址归属地查询References 1. IP 地址归属地查询 https://tool.lu/ip/index.html 2. IP 地址归属地查询 https://www.ip.cn/ip/.html References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/...
实战经验分享:在Java中灵活应用Excel注释和批注
本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 注释及批注是 Excel 中比较常用的功能,注释往往针对单元格,起到解释说明的作用&a…...
AUTOSAR从入门到精通-车载以太网(三)
目录 前言 原理 车载以太网总体架构 物理层 数据链路层 以太网帧格式<...
【自然语言处理】用Python从文本中删除个人信息-第二部分
自我介绍 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【…...
设计模式之-中介者模式,快速掌握中介者模式,通俗易懂的讲解中介者模式以及它的使用场景
系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用…...
12.25
led.c #include "led.h" void all_led_init() {RCC_GPIO | (0X3<<4);//时钟使能GPIOE_MODER &(~(0X3<<20));//设置PE10输出GPIOE_MODER | (0X1<<20);//设置PE10为推挽输出GPIOE_OTYPER &(~(0x1<<10));//PE10为低速输出GPIOE_OSPEED…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
