If it take a background thread before the data arrives, and when many connections waiting for data, there will be too many threads exist, causing performance degradation. is
Socket.BeginReceive()
, and other asynchronous I/O methods in .NET, make use of the IOCP thread pool. The short version is that this is a very efficient way to manage I/O. There is practically no cost to wait for the I/O to complete, and even once it completes, your completion callback is called from a thread pool thread, tying up that thread only for as long as it takes for your callback to complete.
"IOCP" stands for "IO Completion Ports", a feature in the native Windows API. The basic idea is that you can have a single thread, or some small collection of threads, all ready to service the completion of a large number of I/O operations. This allows I/O operations to scale well into the hundreds of thousands, if not millions, of concurrent operations, while still only requiring a relatively small number of threads to deal with them all.
So, go right ahead use those asynchronous I/O APIs. They are the best way to write scalable I/O code.
(Aside: the Socket
class in particular has a number of async options. Ironically, the methods ending in ...Async
do not comply with the new(er) async
/await
paradigm in C#, but they are in fact the most scalable way to do I/O with a Socket
, because not only do they use the IOCP thread pool, they also allow you to reuse your I/O state objects, so you can have a pool of those and minimize GC load.)