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

时间:2018-12-13 10:38:51

标签: c# .net .net-4.7.1

我正在使用网络缓冲区和流,并且“跨度”和“内存”将非常适合应用程序需求。

根据this问题,我想获得一个Stream来接受Span作为参数。我知道它是在.NET Core 2.1中实现的,但是我想知道是否还有一种方法可以在.NET Framework中获得此功能? (我正在使用4.7.1)

类似的东西:

Span<Byte> buffer = new Span<byte>();
stream.Read(buffer);

3 个答案:

答案 0 :(得分:2)

我设法通过为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); }
    }

答案 1 :(得分:1)

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

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

使用System.Memory

检查NuGet

答案 2 :(得分:-2)

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

但是,在某些情况下,当我同时使用针对.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租借/复制/返回数组的小开销。