.NET 中的套接字类有一些新的异步方法(如 Socket.ReceiveAsync
)。
我试图理解他们的目的。据我了解,它们的创建是为了避免创建新的 IAsyncResult
每个操作的对象。
假设我要创建一个高性能 HTTP 服务器。然后我需要为每个操作创建一个 Request 或 Response 对象。请求或响应对象当然也有一些可能是其他类的属性(或者只是原语 + 字符串)。而且我可能必须从数据库中获取信息(要创建更多对象)。
我的观点是每个请求/回复可以创建相当多的对象。是AsyncResult
对象太重以至于会影响整个服务器的性能?或者 MS 是否意味着我应该对服务器中的所有对象使用享元模式(重用请求/回复对象而不是分配新对象)?
请赐教。
更新
从 MSDN 关于新的异步方法:
The main feature of these enhancements is the avoidance of the repeated allocation and synchronization of objects during high-volume asynchronous socket I/O. The Begin/End design pattern currently implemented by the System.Net.Sockets.Socket class requires a System.IAsyncResult object be allocated for each asynchronous socket operation
来源:http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx
更新2
这个问题不是重复的。我不是在问区别。我很清楚其中的区别。如果他们添加了减少分配和 GC 工作的方法,我是否应该在套接字处理之上的协议(protocol)层中做同样的事情?即我应该对像
HttpReqest
这样的对象使用享元模式吗?等等
最佳答案
那么在一个套接字生命周期中,每个开始/结束操作都会分配新的同步对象。
例如,您的逻辑是,
// GET /default.aspx HTTP/1.1<cr-lf>
ReadLine for Http Verb and Version
// Headers
ReadLine till you get empty line and process header
// Data
Read or process mime data
现在,如果您注意到,我们将永远不会在一个开始/结束调用中读取所有内容,而是每个操作将调用多个开始/结束,这将创建新的同步对象。
但是这些所有步骤仅用于一个客户端/服务器通信。
因此,您的请求/响应对象在套接字的整个生命周期中将只有一个,在这种情况下,您最好使用新的 Async 方法并保留您的请求/响应对象
作为一个单一的对象。
当您有一台服务器同时处理 1000 个请求时,这肯定会影响性能。即使同步对象占用 100 个字节但分配/重新分配,gc 处理器使用都将影响 1000 个同时操作。
然而,内存管理存在设计良好的算法,如果您的服务器长时间连续运行,它肯定会导致碎片并且它确实会变慢。
关于.net - 新的异步方法和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6227334/