广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#中的高效IO库System.IO.Pipelines
  • 904
分享到

C#中的高效IO库System.IO.Pipelines

C#高效IO库System.IO.Pipelines 2022-11-13 11:11:56 904人浏览 安东尼
摘要

我们在编写网络程序的时候,经常会进行如下操作: 申请一个缓冲区从数据源中读入数据至缓冲区解析缓冲区的数据重复第2步 表面上看来这是一个很常规而简单的操作,但实际使用过程中往往存在如下

我们在编写网络程序的时候,经常会进行如下操作:

  • 申请一个缓冲区

  • 从数据源中读入数据至缓冲区

  • 解析缓冲区的数据

  • 重复第2步

表面上看来这是一个很常规而简单的操作,但实际使用过程中往往存在如下痛点:

数据读不全:

可能不能在一次read操作中读入所有需要的数据,因此需要在缓冲区中维护一个游标,记录下次读取操作的起始位置,这个游标带了了不小的复杂度:

  • 从缓冲区读数据时,要根据游标计算缓冲区起始写位置,以及剩余空间大小。增加了读数据的复杂度。

  • 解析数据也是复用这个缓冲区的,解析的时候也要判断游标起始位置,剩余空间大小。同时增加了解析数据的复杂度。

  • 解析玩了后还要移动游标,重新标记缓冲区起始位置,再次增加了复杂度。

缓冲区容量有限:

由于缓冲区有限,可能申请的缓冲区不够用,需要引入动态缓冲区。这也大幅加大了代码的复杂度。

  • 如果每次都申请更大的内存,一方面带来的内存申请释放开销,另一方面需要将原来的数据移动,并更新游标,带来更复杂的逻辑。

  • 如果靠多段的内存组成一个逻辑整理,数据的读写方式都比较复杂。

  • 使用完后的内存要释放,如果需要更高的效率还要维持一个内存池。

读和用没有分离

我们的业务本身只关心使用操作,但读和用操作没有分离,复杂的都操作导致用操作也变得复杂,并且严重干扰业务逻辑。

今天介绍微软新推出的一个库:System.io.Pipelines(需要在Nuget上安装),用于解决这些痛点。它主要包含一个Pipe对象,它有一个Writer属性和Reader属性。

var pipe   = new Pipe();
var writer = pipe.Writer;
var reader = pipe.Reader;

Writer对象

Writer对象用于从数据源读取数据,将数据写入管道中;它对应业务中的"读"操作。

var content = Encoding.Default.GetBytes("hello world");
var data    = new Memory<byte>(content);
var result  = await writer.WriteAsync(data);

另外,它也有一种使用Pipe申请Memory的方式

var buffer = writer.GetMemory(512);
content.CopyTo(buffer);
writer.Advance(content.Length);
var result = await writer.FlushAsync();

Reader对象

Reader对象用于从管道中获取数据源,它对应业务中的"用"操作。

首先获取管道的缓冲区:

var result = await reader.ReadAsync();
var buffer = result.Buffer;

这个Buffer是一个ReadOnlySequence<byte>对象,它是一个相当好的动态内存对象,并且相当高效。它本身由多段Memory<byte>组成,查看Memory段的方法有:

  • IsSingleSegment: 判断是否只有一段Memory<byte>

  • First: 获取第一段Memory<byte>

  • GetEnumerator: 获取分段的Memory<byte>

它从逻辑上也可以看成一段连续的Memory<byte>,也有类似的方法:

  • Length: 整个数据缓冲区长度

  • Slice: 分割缓冲区

  • CopyTo: 将内容复制到Span中

  • ToArray: 将内容复制到byte[]中

另外,它还有一个类似游标的位置对象SequencePosition,可以从其Position相关函数中使用,这里就不多介绍了。

这个缓冲区解决了"数据读不够"的问题,一次读取的不够下次可以接着读,不用缓冲区的动态分配,高效的内存管理方式带来了良好的性能,好用的接口是我们能更关注业务。

获取到缓冲区后,就是使用缓冲区的数据

var data = buffer.ToArray();

使用完后,告诉PIPE当前使用了多少数据,下次接着从结束位置后读起

reader.AdvanceTo(buffer.GetPosition(4));

这是一个相当实用的设计,它解决了"读了就得用"的问题,不仅可以将不用的数据下次再使用,还可以实现Peek的操作,只读但不改变游标。

交互

除了"读"和"用"操作外,它们之间还需要一些交互,例如:

  • 读过程中数据源不可用,需要停止使用

  • 使用过程中业务结束,需要中止数据源。

Reader和Writer都有一个Complete函数,用于通知结束:

reader.Complete();
writer.Complete();

在Writer写入和Reader读取时,会获得一个结果

FlushResult result = await writer.FlushAsync();
ReadResult result = await reader.ReadAsync();

它们都有一个IsComplete属性,可以根据它是否为true判断是否已经结束了读和写的操作。

取消

在写入和读取的时候,也可以传入一个CancellationToken,用于取消相应的操作。

writer.FlushAsync(CancellationToken.None);
reader.ReadAsync(CancellationToken.None);

如果取消成功,对应的Result的IsCanceled则为true(没有验证过)

到此这篇关于C#高效IO库System.IO.Pipelines的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: C#中的高效IO库System.IO.Pipelines

本文链接: https://www.lsjlt.com/news/153243.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#中的高效IO库System.IO.Pipelines
    我们在编写网络程序的时候,经常会进行如下操作: 申请一个缓冲区从数据源中读入数据至缓冲区解析缓冲区的数据重复第2步 表面上看来这是一个很常规而简单的操作,但实际使用过程中往往存在如下...
    99+
    2022-11-13
    C# 高效IO库 System.IO.Pipelines
  • C#的高效IO库System.IO.Pipelines怎么使用
    今天小编给大家分享一下C#的高效IO库System.IO.Pipelines怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一...
    99+
    2023-07-02
  • c++中的基本IO类型详解
    引言 c++不直接处理输入和输出,而是通过标准库中的类型处理IO。IO的设备可以是文件、控制台、string。c++主要定义了三种IO类型,分别被包含在iostream、fstrea...
    99+
    2022-11-12
    c++ io类型 c++ io
  • C#中常用的IO操作介绍
    在.Net 4.0中增加了一系列较为实用的IO功能,下面让我们来一起看一下吧: 1. Stream.CopyTo Stream.CopyTo在用于较小的Stream之间的拷贝时还是比...
    99+
    2022-11-13
    C# IO操作
  • c++中的基本IO类型是什么
    这篇文章主要讲解了“c++中的基本IO类型是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“c++中的基本IO类型是什么”吧!引言c++不直接处理输入和输出,而是通过标准库中的类型处理IO...
    99+
    2023-06-19
  • mysql数据库磁盘io高的排查是怎样的
    mysql数据库磁盘io高的排查是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。     最近,数据库会报...
    99+
    2022-10-18
    io mysql
  • Java中常见的IO读写效率对比
    这篇文章主要介绍“Java中常见的IO读写效率对比”,在日常操作中,相信很多人在Java中常见的IO读写效率对比问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中常见的IO读写效率对比”的疑惑有所帮助!...
    99+
    2023-06-17
  • c#中Bitmap转bitmapImage高效方法是什么
    本篇内容介绍了“c#中Bitmap转bitmapImage高效方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! publi...
    99+
    2023-06-25
  • Python中高效的json对比库deepdiff详解
    目录deepdiff是什么deepdiff安装案例1、对比txt文件案例2、对比json工作中我们经常要两段代码的区别,或者需要查看接口返回的字段与预期是否一致,如何快速定位出两者的...
    99+
    2022-11-11
    Python json对比库deepdiff python json对比库 python deepdiff
  • 如何设计高效的C++数据结构?
    作为一门广泛应用于计算机科学的科目,数据结构的设计与优化是C++编程中重要的一环。在面对复杂的数据问题时,高效的数据结构可以大大提升程序的执行效率和减轻计算压力。所以如何设计高效的C++数据结构成为了每个程序员要深入学习和研究的事情。本文将...
    99+
    2023-11-03
    C++ 数据结构 高效设计
  • 如何解析C++中IO流的输入输出流
    本篇文章为大家展示了如何解析C++中IO流的输入输出流,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。介绍流: 若干字节数据从一端到另一端我们叫做流例如:操作文件,从程序到文件,数据的流动的操作称为流...
    99+
    2023-06-22
  • C#中多种高效定时器方法的使用详解
    目录使用 System.Threading.Timer 和 ManualResetEventSlim使用 Stopwatch 和 Sleep 方法使用 Task.Delay 和 as...
    99+
    2023-05-14
    C# 定时器
  • C++中的常用库
    1. cmath: 数学计算 #include <iostream> #include <cmath> using namespace std; in...
    99+
    2022-11-12
    C++常用库
  • C#中多种高效定时器方法怎么使用
    这篇文章主要讲解了“C#中多种高效定时器方法怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#中多种高效定时器方法怎么使用”吧!在 C# 中,定时器是一种常用的机制,可以周期性地执行...
    99+
    2023-07-05
  • Python中的numpy库能否提高并发编程的效率?
    Python作为一种高级编程语言,广泛应用于人工智能、科学计算、数据分析等领域。而在这些领域中,数据处理是一项非常重要的工作。随着数据量的不断增大,数据处理的效率成为了一个非常关键的问题。在这种情况下,numpy库就显得尤为重要了。 nu...
    99+
    2023-11-07
    并发 关键字 numpy
  • C语言中提高代码执行效率的小技巧有哪些
    本篇内容主要讲解“C语言中提高代码执行效率的小技巧有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言中提高代码执行效率的小技巧有哪些”吧!一、方法参数限...
    99+
    2022-10-18
    c语言
  • C#开发建议:高效的调试与故障排查
    C#开发建议:高效的调试与故障排查在软件开发的过程中,调试和故障排查是不可避免的环节。无论是在开发过程中还是在软件上线后,都会遇到各种各样的问题和bug。因此,掌握高效的调试和故障排查技巧是每个C#开发人员都应该具备的能力。本文将分享一些关...
    99+
    2023-11-22
    调试 高效 故障排查
  • CentOS系统中跟踪高IO等待的示例分析
    这篇文章主要为大家展示了“CentOS系统中跟踪高IO等待的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“CentOS系统中跟踪高IO等待的示例分析”这篇文章吧。高IO等待问题的第一个征...
    99+
    2023-06-10
  • 如何使用Java中的NumPy库实现高效的科学计算?
    如何使用Java中的NumPy库实现高效的科学计算? NumPy是Python中用于科学计算的一个开源库,它提供了高效的数值运算和矩阵操作功能。而Java作为另一个流行的编程语言,也可以使用NumPy库来实现高效的科学计算。在本文中,我们将...
    99+
    2023-08-28
    numy shell 并发
  • Android中EasyPermissions官方库高效处理权限的示例分析
    这篇文章给大家分享的是有关Android中EasyPermissions官方库高效处理权限的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。介绍:easypermission库是一个简化基本的系统权限逻辑的...
    99+
    2023-05-30
    android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作