套接字将这些new async methods since .NET 3.5与SocketAsyncEventArgs一起使用(例如Socket.SendAsync()),这样做的好处是可以使用IO完成端口,并且无需继续分配。
我们创建了一个名为 UdpStream 的类,它具有一个简单的界面-仅StartSend和Completed事件。它分配两个SocketAsyncEventArgs,一个用于发送,一个用于接收。 StartSend仅使用SendAsync调度一条消息,并且每秒被调用10次。我们在接收SocketAsyncEventArgs上使用Completed事件,在处理完每个事件之后,我们全部使用ReceiveAsync,以便形成接收循环。同样,我们每秒接收大约10次。
我们的系统最多需要支持这些UdpStream对象的 500 。换句话说,我们的服务器将与500个不同的IP端点并发通信。
我在MSDN SocketAsyncEventArgs示例中注意到,它们分配N x SocketAsyncEventArgs,一次要为每个要处理的未完成的接收操作分配一个。我不清楚这与我们的场景有何关系-在我看来,也许我们没有从SocketAsyncEventArgs中受益,因为我们只是在每个端点上分配一个。如果最终得到500个接收到SocketAsyncEventArgs,我想我们将不会获得任何好处。也许我们仍然可以从IO完成端口中获得一些 yield ?
缩放到500?
与使用较旧的Begin/End API相比,使用SocketAsyncEventArgs有什么好处?
最佳答案
仍然有巨大的好处。
如果使用APM模式(开始/结束方法),则每个BeginSend
和每个BeginReceive
都会分配一个IAsyncResult实例。这意味着每秒大约发生10,000次完整的类/对象分配(500 * 10 [发送] + 500 * 10 [接收])。由于这将增加很多GC压力,因此会在系统中增加大量额外开销。
切换到针对高性能网络应用程序的建议的新方法,您将预分配SocketAsyncEventArgs
实例(500),并将其重新用于每个方法调用,从而消除了在这些操作过程中产生的GC压力。
关于.NET异步套接字: any benefit of SocketAsyncEventArgs over Begin/End in this scenario?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7237670/