C#中System.IO.Pipelines庫的使用詳解
寫在前面
在進(jìn)一步了解Socket粘包分包的過程中,了解到了.NET 中的 System.IO.Pipelines,可以更優(yōu)雅高效的解決這個問題;先跟隨官方的示例做個初步的認(rèn)識。
System.IO.Pipelines 是一個庫,旨在使在 .NET 中執(zhí)行高性能 I/O 更加容易。 該庫的目標(biāo)為適用于所有 .NET 實現(xiàn)的 .NET Standard。
System.IO.Pipelines 具有高性能的流數(shù)據(jù)分析功能,可以減少代碼復(fù)雜性。
老規(guī)矩通過NuGet安裝該類庫
代碼實現(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é)
例子中用到的文本文件是一個以\n 換行符作為結(jié)尾的多行文本,微軟官方示例沒有提供,這個是自己建的測試文件,如果沒有檢測到\n會拋出異常。
從運(yùn)行的結(jié)果可以看到,從傳入的流中識別以\n結(jié)尾,作為數(shù)據(jù)塊的區(qū)分,利用這個特性定義數(shù)據(jù)報文的尾部,實現(xiàn)分包。
到此這篇關(guān)于C#中System.IO.Pipelines庫的使用詳解的文章就介紹到這了,更多相關(guān)C# System.IO.Pipelines內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c# 應(yīng)用NPOI獲取Excel中的圖片,保存至本地的算法
本文主要介紹了c# 應(yīng)用NPOI獲取Excel中的圖片,保存至本地的算法。具有很好的參考價值,下面跟著小編一起來看下吧2017-02-02C#使用OpenCvSharp4庫讀取電腦攝像頭數(shù)據(jù)并實時顯示
OpenCvSharp4庫是一個基于.Net封裝的OpenCV庫,本文主要給大家介紹了C#使用OpenCvSharp4庫讀取電腦攝像頭數(shù)據(jù)并實時顯示的詳細(xì)方法,感興趣的朋友可以參考下2024-01-01C# Lambda表達(dá)式select()和where()的區(qū)別及用法
這篇文章主要介紹了C# Lambda表達(dá)式select()和where()的區(qū)別及用法,select在linq中一般會用來提取最后篩選的元素集合,在lambda表達(dá)式中通常用where得到元素集合,需要的朋友可以參考下2023-07-07C# WinForm 登錄界面的圖片驗證碼(區(qū)分大小寫+不區(qū)分大小寫)
這篇文章主要介紹了C# WinForm 登錄界面的圖片驗證碼(區(qū)分大小寫+不區(qū)分大小寫),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02c#中Winform實現(xiàn)多線程異步更新UI(進(jìn)度及狀態(tài)信息)
本篇文章主要介紹了c#中Winform實現(xiàn)多線程異步更新UI(進(jìn)度及狀態(tài)信息) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02如何在C#中使用 CancellationToken 處理異步任務(wù)
這篇文章主要介紹了如何在C#中使用 CancellationToken 處理異步任務(wù),幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-03-03