C# 将 span 与 SocketAsyncEventArgs 结合使用

标签 c# sockets .net-core unsafe

我想使用新的 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/

相关文章:

c# - 警告尝试构建 Service Fabric AspNetCore2 项目

C# Path.Combine 没有使用 AppData 位置

c# - 是否可以通过从应用程序中获取值而不在 WP7 中触发它来更新动态磁贴?

javascript - 当不使用选项卡时如何禁用socket.io,因为该选项卡占用大量RAM并且连接过多

node.js - socket.io 1.2.1 如何在重新连接后修复双重事件

c# - 内联变量声明不编译

c# - 启动一个执行委托(delegate)的新进程

c# - 如何在c#代码中在iis 5.1中添加新的应用程序池?

c - 将数据写入以 2 帧发送的套接字

c# - 如何在 .NET Core 2.0 中包含库