我想使用新的 Span 将非托管数据直接发送到使用 SocketAsyncEventArgs
的套接字但似乎 SocketAsyncEventArgs
只能接受Memory<byte>
不能用 byte *
初始化或 IntPt
请问有没有一种方法可以将 span 与 SocketAsyncEventArgs
一起使用? ?
感谢您的帮助。
最佳答案
正如评论中已经提到的,Span 在这里是错误的工具——你有没有考虑过使用 Memory反而?正如您所说, SetBuffer
method确实接受它作为参数 - 你有什么理由不能使用它吗?
另见 this article有关堆栈与堆分配如何应用于 Span 和 Memory 的很好解释。它包括这个例子,使用 readonly Memory<Foo> buffer
:
public struct Enumerable : IEnumerable<Foo>
{
readonly Stream stream;
public Enumerable(Stream stream)
{
this.stream = stream;
}
public IEnumerator<Foo> GetEnumerator() => new Enumerator(this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public struct Enumerator : IEnumerator<Foo>
{
static readonly int ItemSize = Unsafe.SizeOf<Foo>();
readonly Stream stream;
readonly Memory<Foo> buffer;
bool lastBuffer;
long loadedItems;
int currentItem;
public Enumerator(Enumerable enumerable)
{
stream = enumerable.stream;
buffer = new Foo[100]; // alloc items buffer
lastBuffer = false;
loadedItems = 0;
currentItem = -1;
}
public Foo Current => buffer.Span[currentItem];
object IEnumerator.Current => Current;
public bool MoveNext()
{
if (++currentItem != loadedItems) // increment current position and check if reached end of buffer
return true;
if (lastBuffer) // check if it was the last buffer
return false;
// get next buffer
var rawBuffer = MemoryMarshal.Cast<Foo, byte>(buffer);
var bytesRead = stream.Read(rawBuffer);
lastBuffer = bytesRead < rawBuffer.Length;
currentItem = 0;
loadedItems = bytesRead / ItemSize;
return loadedItems != 0;
}
public void Reset() => throw new NotImplementedException();
public void Dispose()
{
// nothing to do
}
}
}
关于C# 将 span 与 SocketAsyncEventArgs 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52210512/