А насчет асинхронных и не блокируемых я что то окончательно запутался
Асинхронный - это в параллельном потоке. Тот же BeginConnect запускает Connect в отдельном потоке, а EndConnect получает результат.
Неблокирующая операция ввода-вывода - это другое. Для этого не создаётся отдельных потоков, а на уровне ядра операционной системы происходит управление устройствами ввода-вывода, работа которых на порядки медленнее работы центрального процессора. За ввод-вывод отвечают соответствующие устройства компьютера и их драйверы. Результаты (в твоём случае ввода) накапливаются в очередях и по окончании операции возникает событие готовности, что операция завершена. При помощи специальных средств программа, работающая в 1 поток на процессоре, может обслуживать множество параллельных операций ввода-вывода. В основном обслуживание заключается в запуске нескольких неблокирующих операций чтения, обработки результатов по мере готовности и запуске неблокирующих операций записи. Это делается в цикле. Сам этот подход к обработке называется мультиплексированием. Чем-то это похоже на жонглёра, который подбрасывает тарелочки: пока бОльшая часть тарелочек летит в воздухе, он обслуживает лишь одну (ловит и подбрасывает на новый круг), при этом работа жонглёра строго последовательна, но все тарелочки движутся параллельно.
Что же касается AsyncConnect, то по большому счёту это мало отличается от Begin/EndConnect. Разница может быть в том, что в одном случае запускается новый поток, а в другом - используется механизм заданий для системного пула потоков (к сожалению, в MSDN на уровне описания класса этот вопрос не раскрыт).
Работа с пулом потоков имеет меньше накладных расходов (поскольку нет запуска новых потоков), но при этом количество потоков ограничено (по умолчанию 25), и сами задания выстраиваются в очередь. Короче говоря, параллельно будут работать лишь столько заданий, сколько есть потоков, а остальные будут отложены. Как я понимаю, это не то, что тебе нужно.