C# 初识System.IO.Pipelines

2023-12-26 06:12

本文主要是介绍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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538356

相关文章

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

Linux操作系统 初识

在认识操作系统之前,我们首先来了解一下计算机的发展: 计算机的发展 世界上第一台计算机名叫埃尼阿克,诞生在1945年2月14日,用于军事用途。 后来因为计算机的优势和潜力巨大,计算机开始飞速发展,并产生了一个当时一直有效的定律:摩尔定律--当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。 那么相应的,计算机就会变得越来越快,越来越小型化。

Java IO 操作——个人理解

之前一直Java的IO操作一知半解。今天看到一个便文章觉得很有道理( 原文章),记录一下。 首先,理解Java的IO操作到底操作的什么内容,过程又是怎么样子。          数据来源的操作: 来源有文件,网络数据。使用File类和Sockets等。这里操作的是数据本身,1,0结构。    File file = new File("path");   字

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

Partical System

创建"粒子系统物体"(点击菜单GameObject -> Create Other -> Particle System) 添加"粒子系统组件"(点击Component -> Effects  ->Particle System) 粒子系统检视面板  点击粒子系统检视面板的右上角的"+"来增加新的模块。(Show All Modules:显示全部) 初始化模块: •

C# dateTimePicker 显示年月日,时分秒

dateTimePicker默认只显示日期,如果需要显示年月日,时分秒,只需要以下两步: 1.dateTimePicker1.Format = DateTimePickerFormat.Time 2.dateTimePicker1.CustomFormat = yyyy-MM-dd HH:mm:ss Tips:  a. dateTimePicker1.ShowUpDown = t

C#关闭指定时间段的Excel进程的方法

private DateTime beforeTime;            //Excel启动之前时间          private DateTime afterTime;               //Excel启动之后时间          //举例          beforeTime = DateTime.Now;          Excel.Applicat

C# 防止按钮botton重复“点击”的方法

在使用C#的按钮控件的时候,经常我们想如果出现了多次点击的时候只让其在执行的时候只响应一次。这个时候很多人可能会想到使用Enable=false, 但是实际情况是还是会被多次触发,因为C#采用的是消息队列机制,这个时候我们只需要在Enable = true 之前加一句 Application.DoEvents();就能达到防止重复点击的问题。 private void btnGenerateSh