C#中System.IO.Pipelines庫的使用詳解
寫在前面
在進(jìn)一步了解Socket粘包分包的過程中,了解到了.NET 中的 System.IO.Pipelines,可以更優(yōu)雅高效的解決這個(gè)問題;先跟隨官方的示例做個(gè)初步的認(rèn)識(shí)。
System.IO.Pipelines 是一個(gè)庫,旨在使在 .NET 中執(zhí)行高性能 I/O 更加容易。 該庫的目標(biāo)為適用于所有 .NET 實(shí)現(xiàn)的 .NET Standard。
System.IO.Pipelines 具有高性能的流數(shù)據(jù)分析功能,可以減少代碼復(fù)雜性。
老規(guī)矩通過NuGet安裝該類庫

代碼實(shí)現(xiàn)
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 thrown
reader.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));
}調(diào)用示例

總結(jié)
例子中用到的文本文件是一個(gè)以\n 換行符作為結(jié)尾的多行文本,微軟官方示例沒有提供,這個(gè)是自己建的測(cè)試文件,如果沒有檢測(cè)到\n會(huì)拋出異常。

從運(yùn)行的結(jié)果可以看到,從傳入的流中識(shí)別以\n結(jié)尾,作為數(shù)據(jù)塊的區(qū)分,利用這個(gè)特性定義數(shù)據(jù)報(bào)文的尾部,實(shí)現(xiàn)分包。
到此這篇關(guān)于C#中System.IO.Pipelines庫的使用詳解的文章就介紹到這了,更多相關(guān)C# System.IO.Pipelines內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入理解C#實(shí)現(xiàn)快捷鍵(系統(tǒng)熱鍵)響應(yīng)的方法
本篇文章是對(duì)使用C#實(shí)現(xiàn)快捷鍵(系統(tǒng)熱鍵)響應(yīng)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C#實(shí)現(xiàn)批量刪除PDF頁面(單頁/多頁)的實(shí)戰(zhàn)技巧
在自動(dòng)化文檔處理流程中,PDF 文件可能因?qū)С鲥e(cuò)誤、內(nèi)容重復(fù)或格式轉(zhuǎn)換問題而包含多余頁面,本文演示如何使用免費(fèi)庫 Free Spire.PDF for .NET 刪除 PDF 文件中的單個(gè)或多個(gè)頁面,希望對(duì)大家有所幫助2026-04-04
詳解C#如何實(shí)現(xiàn)隱式類型轉(zhuǎn)換
Result?類型是許多編程語言中處理錯(cuò)誤的常用方式,包括?C#?的?dotNext?庫。在本文中,我們將通過例子回顧?C#?中?using?語句和隱式類型轉(zhuǎn)換的使用,感興趣的可以了解一下2023-01-01
C# 中 Array和 ArrayList詳解及區(qū)別
這篇文章主要介紹了C# 中 Array和 ArrayList詳解及區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-01-01
C#基于TimeSpan實(shí)現(xiàn)倒計(jì)時(shí)效果的方法
這篇文章主要介紹了C#基于TimeSpan實(shí)現(xiàn)倒計(jì)時(shí)效果的方法,比較實(shí)用的功能,需要的朋友可以參考下2014-08-08

