首页 文章

.NET异步套接字:在这种情况下SocketAsyncEventArgs在Begin / End上的任何好处是什么?

提问于
浏览
5

Socket有这些new async methods since .NET 3.5用于SocketAsyncEventArgs(例如Socket.SendAsync()),有利于他们使用IO完成端口并避免需要继续分配 .

我们用一个简单的接口创建了一个名为 UdpStream 的类 - 只需要StartSend和一个Completed事件 . 它分配两个SocketAsyncEventArgs,一个用于发送,一个用于接收 . StartSend只是使用SendAsync调度消息,并且每秒调用大约10次 . 我们在接收SocketAsyncEventArgs上使用Completed事件,并在处理完每个事件后,我们所有的ReceiveAsync都会形成一个接收循环 . 同样,我们每秒大约收到10次 .

我们的系统需要支持最多 500 的这些UdpStream对象 . 换句话说,我们的服务器将与500个不同的IP endpoints 同时通信 .

我注意到在MSDN SocketAsyncEventArgs示例中他们分配了N x SocketAsyncEventArgs,一个用于您希望一次处理的每个未完成的接收操作 . 我不清楚这与我们的场景究竟有什么关系 - 在我看来,也许我们没有得到SocketAsyncEventArgs的好处,因为我们只是为每个 endpoints 分配一个 . 如果我们最终获得500个SocketAsyncEventArgs,我认为我们将无法获益 . 也许我们仍然可以从IO完成端口获得一些好处?

  • Does this design make correct use of SocketAsyncEventArgs when scaling to 500?

  • For the case where we have a single "UdpStream" in use, is there any benefit to using SocketAsyncEventArgs vs using the older Begin/End API?

2 回答

  • 10

    在我看来,也许我们没有得到SocketAsyncEventArgs的好处,因为我们只是为每个 endpoints 分配一个 . 如果我们最终获得500个SocketAsyncEventArgs,我认为我们将无法获益 .

    仍然有很大的好处 .

    如果使用APM模式(开始/结束方法),则每个 BeginSend 和每个 BeginReceive 分配一个IAsyncResult实例 . 这意味着's a full class/object allocation occurring roughly 10,000 times per second (50010 [send] + 50010 [receive]). This puts a huge amount of extra overhead in the system since it'将增加很多GC压力 .

    切换到高性能网络应用程序的新建议方法,您需要预先分配 SocketAsyncEventArgs 实例(500)并在每次方法调用时重复使用它们,从而消除在这些操作期间创建的GC压力 .

  • 6

    Socket具有这些新的异步方法,因为.NET 3.5与SocketAsyncEventArgs(例如Socket.SendAsync())一起使用,有利于它们使用IO完成端口并避免需要继续分配 .

    Begin / End方法也使用IO完成端口 .

    对于我们使用单个“UdpStream”的情况,使用SocketAsyncEventArgs与使用旧的Begin / End API相比有什么好处?

    imho你应该坚持你所知道的,因为你会让产品更快地运行起来 . 但我也会创建一个严格的IO处理类来处理传输 . 如果传输性能被证明是瓶颈,则可以更轻松地切换到新模型 .

相关问题