То, что вы пытаетесь сделать, называется асинхронным шаблоном в терминологии Microsoft.Общая идея состоит в том, чтобы изменить все операции блокировки ввода-вывода на неблокирующие.Если это сделано, приложению обычно требуется столько системных потоков, сколько имеется ядер ЦП на компьютере.
Взгляните на библиотеку параллельных задач в .Net 4: http://msdn.microsoft.com/en-us/library/dd460717%28VS.100%29.aspx
Этодовольно зрелая оболочка поверх простой старой парадигмы Begin / Callback / Context .Net.
Обновление:
Подумайте, что вы будете делать с данными после того, как прочитаете из соединения.В реальной жизни вам, вероятно, придется ответить клиенту или сохранить данные в файл.В этом случае вам потребуется некоторая инфраструктура C # для хранения / управления вашей логикой и при этом оставаться в одном потоке.TPL предоставляет его вам бесплатно.Единственным недостатком является то, что он был введен в .Net 4, поэтому, вероятно, он еще не в Mono.
Еще одна вещь, которую следует учитывать, это время жизни соединения.Как часто ваши связи открываются / закрываются и как долго они живут?Это важно, потому что принятие и отключение TCP-соединения требует обмена пакетами с клиентом (который по своей природе является асинхронным, и более того - злонамеренный клиент может вообще не возвращать ACK (подтвержденные) пакеты).Если вы считаете, что этот аспект важен для вашего приложения, вы, возможно, захотите изучить, как правильно с этим справиться в .Net.В WinAPI соответствующими функциями являются AcceptEx и DisconnectEx.Вероятно, они заключены в .Net с методами Begin / End - в этом случае вы можете пойти.В противном случае вам, вероятно, придется создать оболочку для этих вызовов WinAPI.