ReadOnlySpan
可以说现在高性能操作的重要基石
其原理有兴趣的同学可以看 2018 的介绍Span
文章
其为了保障大家安全使用做了相应的限制
那么有没方法绕过呢?
在class中持有 ReadOnlySpan
直接持有是不可能的,本身为 ref struct
就保障了大家写不出持有它的代码
但是我们可以玩骚操作,无法持有你,我们可以创造一个一模一样的你
如下面代码,我们获取span 对应的指针
public unsafe class ReadOnlySpanReaderBuffer
{
internal void* _buffer;
internal int _length;
public ReadOnlySpanReaderBuffer(Span span)
{
_buffer = Unsafe.AsPointer(ref span.GetPinnableReference());
_length = span.Length;
}
public ReadOnlySpanReaderBuffer(ReadOnlySpan span)
{
_buffer = Unsafe.AsPointer(ref MemoryMarshal.GetReference(span));
_length = span.Length;
}
在需要使用的时候通过指针重新创建一个一模一样的span
public ReadOnlySpan Readed
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new ReadOnlySpan(_buffer, _length);
}
将 Span 转换成 Memory
同样出于安全考虑,默认Span
无法转换成 Memory
但是我们可以玩骚操作,无法转换你,我们可以创造一个
首先我们需要建立一个Memory的基础类, 通过它来告诉 Memory
如何拿去我们从 Span
里面偷出来的指针
public sealed unsafe class UnmanagedMemoryManager : MemoryManager
{
private readonly T* _pointer;
private readonly int _length;
public UnmanagedMemoryManager(Span span)
{
fixed (T* ptr = &MemoryMarshal.GetReference(span))
{
_pointer = ptr;
_length = span.Length;
}
服务器托管网 }
public UnmanagedMemoryManager(T* pointer, int length)
{
if (length GetSpan() => new Span(_pointer, _length);
// 一切的关键就在这个方法
public override MemoryHandle Pin(int elementIndex = 0)
{
if (elementIndex = _length)
throw new ArgumentOutOfRangeException(nameof(elementIndex));
return new MemoryHandle(_pointer + elementIndex);
}
public override void Unpin() { }
protected override void Dispose(bool disposing) { }
}
在需要使用的时候通过指针重新创建一个一模一样的Memory
public ReadOnlyMemory Read服务器托管网edMemory
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new UnmanagedMemoryManager((IntPtr)_buffer, _length).Memory;
}
道路千万条,安全第一条,大家慎用骚操作啊
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: Taurus.MVC WebMVC 入门开发教程4:数据列表绑定List
前言: 在本篇 Taurus.MVC WebMVC 入门开发教程的第四篇文章中, 我们将学习如何实现数据列表的绑定,通过使用 List 来展示多个数据项。 我们将继续使用 Taurus.Mvc 命名空间,同时探讨如何在视图中绑定并显示一个 Model 列表。 …