Reading through the SendAsync, BeginAsync method illustrations of Sockets, I realized that it was suggested to pool SocketAsyncEventArgs instances saying that it is a better than BeginXX, EndXX async approach since each call creates an IAsyncResult instance.
I thought it was not that a great practice to pool objects that can be instantiated easily (such as SocketAsyncEventArgs). Object allocation is pretty fast and GC is optimized to handle short living objects efficiently. I tried that out implementing a pooling mechanism to see how it performs, actually allocation is faster on simple objects that do nothing but encapsulate some data in ctor. (Well, it was like profiling a DBMS by sending billions of SELECT 1 statements, that’s why I’m here.)
I’m not asking which is better, I believe profiling the actual application would yield the answer but just curious about the benefits of pooling simple short living objects. Better GC performance? Low memory fragmentation? Does it worth to consider it during design?
From 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.In the new System.Net.Sockets.Socket
class enhancements, asynchronous
socket operations are described by
reusable SocketAsyncEventArgs objects
allocated and maintained by the
application. High-performance socket
applications know best the amount of
overlapped socket operations that must
be sustained. The application can
create as many of the
SocketAsyncEventArgs objects that it
needs. For example, if a server
application needs to have 15 socket
accept operations outstanding at all
times to support incoming client
connection rates, it can allocate 15
reusable SocketAsyncEventArgs objects
for that purpose.
Thanks.
The
IAsyncResultinterface includes anAsyncWaitHandleproperty of typeWaitHandle. AWaitHandleconsumes operating system resources.In fact,
WaitHandleimplements theIDisposableinterface, so the class implementingIAsyncResultshould itself implementIDisposable.This is all to say that hundreds of
IAsyncResultinstances lying around is not a memory issue – it’s a resources issue. The new socket calls get rid of the need for hundreds ofIDisposableobjects lying around.