为了账号安全,请及时绑定邮箱和手机立即绑定

.NET 框架中的 Span<T> 和流

.NET 框架中的 Span<T> 和流

C#
MM们 2022-06-12 15:19:01
我正在使用网络缓冲区和流,Span 和 Memory 非常适合应用程序要求。根据这个问题,我想让一个 Stream 接受 Span 作为参数。我知道这是在 .NET Core 2.1 中实现的,但我想知道是否有办法在 .NET Framework 中获得此功能?(我使用的是 4.7.1)就像是:Span<Byte> buffer = new Span<byte>(); stream.Read(buffer);
查看完整描述

3 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

我设法通过为 Stream 类编写扩展方法并实现 .NET Core 处理 Span 的默认行为来解决这个问题。


    public static int Read(this Stream thisStream, Span<byte> buffer)

    {

        byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);

        try

        {

            int numRead = thisStream.Read(sharedBuffer, 0, buffer.Length);

            if ((uint)numRead > (uint)buffer.Length)

            {

                throw new IOException(SR.IO_StreamTooLong);

            }

            new Span<byte>(sharedBuffer, 0, numRead).CopyTo(buffer);

            return numRead;

        }

        finally { ArrayPool<byte>.Shared.Return(sharedBuffer); }

    }


    public static void Write(this Stream thisStream, ReadOnlySpan<byte> buffer)

    {

        byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);

        try

        {

            buffer.CopyTo(sharedBuffer);

            thisStream.Write(sharedBuffer, 0, buffer.Length);

        }

        finally { ArrayPool<byte>.Shared.Return(sharedBuffer); }

    }


查看完整回答
反对 回复 2022-06-12
?
郎朗坤

TA贡献1921条经验 获得超9个赞

不幸的是,由于此功能尚未在 .Net Standard 中实现,因此未包含在 .Net Framework 中。

编辑:我记得我从某处读到有可以与.Net Framework 一起使用的预发布NuGet 包

检查 NuGetSystem.Memory


查看完整回答
反对 回复 2022-06-12
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

公认的解决方案效果很好!


但是,在某些情况下,我同时使用面向 .NET Core 和 .NET Framework 的共享项目,我同时使用数组和Span<T>:


var _buffer = new byte[1024*1024];

Span<Byte> buffer = _buffer;


#if NETCOREAPP3_1


stream.Read(buffer);


#else


stream.Read(_buffer);


#endif

通过这种方式,我可以避免从 ArrayPool 租用/复制/返回数组的小开销。


查看完整回答
反对 回复 2022-06-12
  • 3 回答
  • 0 关注
  • 265 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信