首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结合使用span和SocketAsyncEventArgs的C#

结合使用span和SocketAsyncEventArgs的C#
EN

Stack Overflow用户
提问于 2018-09-07 02:53:44
回答 3查看 903关注 0票数 11

我想使用新的跨度来使用SocketAsyncEventArgs将非托管数据直接发送到套接字,但SocketAsyncEventArgs似乎只能接受Memory<byte>,这不能用byte *IntPtr进行初始化。

那么,有没有办法在SocketAsyncEventArgs中使用span呢

谢谢你的帮助。

EN

回答 3

Stack Overflow用户

发布于 2018-09-19 00:29:13

正如评论中已经提到的,Span在这里是一个错误的工具--你有没有考虑过改用Memory?正如您所说的,SetBuffer method确实接受它作为参数--有什么原因不能使用它吗?

有关堆栈与堆分配如何应用于跨度和内存的详细说明,请参阅this article。它包含了这个使用readonly Memory<Foo> buffer的示例

代码语言:javascript
复制
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
        }
    }
}
票数 4
EN

Stack Overflow用户

发布于 2018-09-17 11:34:22

您应该首先将数据复制到托管内存,使用Marshal或Buffer类。

如果不是,想想当C代码删除返回的指针时,发送数据会发生什么?

票数 0
EN

Stack Overflow用户

发布于 2018-09-21 19:20:53

SocketAsyncEventArgs (just follow the link)的MSDN页面上有一个完整的示例(以及类的实现)。它显示了类的正确使用,并可能为您提供您正在寻找的指导。

此外,正如Shingo所说,它应该都在托管代码中,而不是在指针中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52210512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档