Await/Async 还是 SocketAsyncEventArgs?

3

我已经使用SocketAsyncEventArgs和socket.***Async方法编写了一个tcp服务器。但我很喜欢使用Stream.ReadAsyncStream.WriteAsync方法来使用await/async方式编写代码。

在性能/内存方面有什么区别,还是我只是在语法上做出了差异?


2
使用SocketAsyncEventArgs API的唯一好处是对于非常高流量/低延迟的服务器来说,可以减少GC需要执行的工作量。通常情况下,在使用其他API时,我不会考虑使用它,除非我发现可衡量的内存问题。话虽如此,我相信Stephen Toub创建了一些关于SocketAsyncEventArgs API的包装器,用于异步/等待操作。我会找出一个链接。 - spender
7
Tada!! : http://blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx - spender
1
顺便提一下,我不建议使用SocketAsyncEventArgs API的原因是由于MS推荐的SocketAsyncEventArgs实例池化所带来的额外复杂性。这使得代码看起来相当丑陋...为了让你了解性能水平,我们使用Stream API运行具有约10000个永久连接客户端的服务器,没有任何问题。 - spender
这些服务器上使用的是什么类型的硬件?是 EC2 吗? 你能把这些评论转化成一个回答吗? - Robin Heggelund Hansen
你还没有回答我的硬件问题。另外,如果你能把这些评论作为答案提供,我可以接受它 :) - Robin Heggelund Hansen
1
使用Stephen Toub的博客文章中的示例,我编写了一些类来等待异步套接字操作、缓存参数并管理缓冲区而不会出现碎片化。您可以在这里找到它。 - Şafak Gür
1个回答

3
使用SocketAsyncEventArgs的优点是减少对垃圾收集器的压力,并将套接字缓冲区分组以防止内存不足异常。
通过使用SocketAsyncEventArgs池,您可以消除为每个读写调用创建和收集IAsyncResult的需要。
其次,每个SocketAsyncEventArgs可以分配大型byte[]块的一部分。这可以防止内存碎片化,有助于减少内存占用。虽然使用Begin/End调用也可以实现此操作,但将每个SocketAsyncEventArgs永久分配到自己的缓冲区中比在每次使用Begin/End方法时分配块更容易。
最后一个重要的区别是,根据MSDN库的说法,Begin/End Send方法可能会在套接字缓冲区满时阻塞。SocketAsyncEventArgs不会阻塞,而是仅根据套接字缓冲区中的空间量写入一定数量的字节,回调将指定已写入的字节数。
除非遇到指定的问题,否则这些优点实际上并不明显。建议您选择最舒适和可维护的方法。

嗨。很抱歉这么晚才加入问题。SocketAsyncEventArgs的好处是否可以用Memory<byte>和ReadOnlySpan<byte>来替代? - uriDium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接